This is a Django-based personal portfolio website with:
- portfolio home page
- projects listing page
- project detail page
- Django admin panel
- Razorpay payment flow for source code purchase
- email sending after successful payment
- fallback JSON data for projects, education, and certificates
This project uses two content sources:
-
Database content
- Managed from Django admin
- Best for normal updates
-
Fallback JSON content
- Used when database data is missing
- Also useful when you want to manage data manually from files
The website now merges both:
- if a project exists in the database and JSON with the same
slug, the database version wins - if a project exists only in JSON, it will still show on the website
- same idea is used for education and certificates
So you do not need to keep editing myApp/views.py.
Is project me content 2 jagah se aa sakta hai:
-
Database se
- Django admin panel se manage hota hai
- Regular updates ke liye best
-
JSON files se
- Jab DB me data na ho tab fallback ke liye
- Ya jab manually file edit karna ho
Ab system dono ko merge karta hai:
- agar same
slugwala project DB aur JSON dono me hai, to DB wala show hoga - agar koi project sirf JSON me hai, to wo bhi site par show hoga
Matlab ab views.py me baar-baar changes karne ki zarurat nahi hai.
-
myApp/views.py- page rendering
- payment flow
- email sending
- JSON fallback loading
-
myApp/models.py- database models for:
EducationCertificateProject
- database models for:
-
myApp/fallback_data/projects.json- manual fallback project data
-
myApp/fallback_data/education.json- manual fallback education data
-
myApp/fallback_data/certificates.json- manual fallback certificate data
-
templates/index.html- homepage UI
-
templates/projects.html- all projects page
-
templates/project_detail.html- single project detail page
-
myPortfolio_2025/settings.py- Django settings
-
.env- secrets and environment variables
For projects, education, and certificates:
- Django first tries to load data from the database
- Then fallback JSON data is loaded
- Both are merged
- Database items get priority if duplicates exist
Flow simple hai:
- Pehle DB se data aata hai
- Phir JSON fallback load hota hai
- Dono merge hote hain
- Agar duplicate mila to DB wala data priority leta hai
.\venv\Scripts\activate
python manage.py runserverOpen:
http://127.0.0.1:8000/- admin:
http://127.0.0.1:8000/admin/
You have 2 ways.
Use this if your deployment/storage supports uploads properly.
Steps:
- Open
/admin - Go to
Projects - Click
Add Project - Fill:
slugtitleshort_descriptionlong_descriptiontech_stackhighlightsdemo_urlsource_code_price_inris_featuredorder
On Vercel, file uploads to local disk do not work because filesystem is read-only.
So for deployed site, prefer:
image_pathfor project imagesource_code_urlfor downloadable zip URL
Edit:
myApp/fallback_data/projects.json
Add a new object like this:
{
"slug": "my-new-project",
"title": "My New Project",
"short_description": "Short summary of the project.",
"long_description": "Detailed project description here.",
"tech_stack": ["Django", "HTML", "CSS", "JavaScript"],
"highlights": ["Responsive UI", "Admin dashboard", "Fast performance"],
"image_path": "images/projects/img/my-new-project.png",
"demo_url": "https://example.com",
"source_code_price_inr": 499,
"source_code_zip": "source_code/zip_files/my-new-project.zip",
"source_code_url": "/static/source_code/my-new-project.zip",
"is_featured": true,
"order": 7
}Agar new project add karna hai aur easy rakhna hai, to:
myApp/fallback_data/projects.jsonkholo- Same format ka ek naya project object add karo
slugunique rakhoimage_pathme image ka path ya URL dosource_code_urlme zip file ka public link dois_featured: truerakhoge to homepage par bhi show hoga
-
slug- unique id for project
- example:
med-store-plus
-
title- project name shown on UI
-
short_description- short text for project cards
-
long_description- full description for project detail page
-
tech_stack- list of technologies
-
highlights- list of major project points
-
image_path- image path or public image URL
-
demo_url- live project link
-
source_code_price_inr- price in INR
-
source_code_zip- internal/source file path reference
-
source_code_url- public URL for sending source code after payment
-
is_featured- if
true, project appears on homepage featured section
- if
-
order- controls display order
Edit:
myApp/fallback_data/education.json
Add a new item:
{
"title": "BCA",
"institution": "Example University",
"date_range": "2026 - 2029",
"description": "Description here.",
"order": 6
}Study/education add karne ke liye:
myApp/fallback_data/education.jsonkholo- Naya object add karo
orderka number decide karega kis sequence me show hoga
Edit:
myApp/fallback_data/certificates.json
Add a new item:
{
"title": "My Certificate",
"issuer": "Issuer Name",
"issued_date": "January 2026",
"drive_link": "https://drive.google.com/your-link",
"order": 8
}Certificate add karne ke liye:
myApp/fallback_data/certificates.jsonkholo- Naya certificate object add karo
drive_linkme public link doorderse position control hogi
Vercel uses a read-only filesystem for deployed Django apps. Because of that:
- uploading images to
media/ - uploading zip files to
media/
does not work in production on Vercel.
Vercel par local file upload kaam nahi karta kyunki deployed server ka filesystem read-only hota hai.
Isliye:
- admin me image upload
- admin me zip upload
production me fail ho sakta hai.
Use:
image_pathwith public image URLsource_code_urlwith public zip URL
Or integrate external storage later:
- Cloudinary
- Supabase Storage
- AWS S3
Current flow:
- User opens a project detail page
- User enters email
- Razorpay order is created
- User completes payment
- Payment is verified
- Email is sent to buyer
- Admin notification is sent
Payment flow ye hai:
- User project detail page open karta hai
- Apna email deta hai
- Razorpay order banta hai
- Payment complete hota hai
- Payment verify hota hai
- Buyer ko email jata hai
- Aapko bhi notification milti hai
These should stay in .env or Vercel Environment Variables.
Examples:
SECRET_KEY=your-secret-key
DEBUG=false
ALLOWED_HOSTS=ayushcodespy.vercel.app
DATABASE_URL=your-database-url
RAZORPAY_KEY_ID=your-razorpay-key
RAZORPAY_KEY_SECRET=your-razorpay-secret
EMAIL_HOST=smtp.gmail.com
EMAIL_PORT=465
EMAIL_HOST_USER=your-email@gmail.com
EMAIL_HOST_PASSWORD=your-app-password
EMAIL_USE_SSL=true
EMAIL_USE_TLS=false
DEFAULT_FROM_EMAIL=your-email@gmail.com
PORTFOLIO_ADMIN_EMAIL=your-email@gmail.com
SITE_URL=https://ayushcodespy.vercel.app
EMAIL_LOGO_URL=https://ayushcodespy.vercel.app/static/images/ayush.pngCheck these things:
slugis unique- JSON syntax is valid
- comma placement in JSON is correct
- image path is correct
- project is either in DB or in fallback JSON
- if DB has same slug, DB version may override JSON version
- if homepage section is involved, check
is_featured
Make sure the image path matches the real file name:
images/projects/img/med-store-plus.png
- use admin for text/content updates when possible
- use fallback JSON for quick manual updates
- use public image/zip URLs on deployed Vercel site
For your current setup:
- Keep admin for normal content
- Keep JSON as backup/manual source
- Use
image_pathandsource_code_urlinstead of upload fields on Vercel
Later, if needed, we can add:
- Cloudinary for image uploads
- Supabase Storage for zip files
- a custom dashboard to edit JSON from UI
- import/export sync between DB and JSON
Edit:
myApp/fallback_data/projects.json
Edit:
myApp/fallback_data/education.json
Edit:
myApp/fallback_data/certificates.json
- add/update from Django admin
- DB version gets priority
If you want, next I can also add:
- a
sample_project.jsontemplate - comments/examples in a separate docs file
- a small script to validate JSON before you run the project