Designing Resume Management for My Placement Portal: Storage, Validation, and Scalability
With the job application workflow taking shape, the next logical step in my Placement Portal is Resume Management.
At first, uploading a resume seems like a simple feature. Add a file field, save the document, and you're done.
But once you start thinking about storage, validation, and scalability, it quickly becomes a design problem rather than just a file upload.
Designing the Resume Model
I started by creating a dedicated Resume model.
Each resume belongs to a specific student, establishing a one-to-many relationship where a student can manage multiple resumes.
Along with the uploaded file, I decided to store additional metadata:
- Student relationship
- Resume file
- File name
- File size (in KB)
Keeping this metadata readily available makes it easier to display resume information without repeatedly inspecting the uploaded file.
Why Store the File Size?
Although Django's file object exposes its size, I chose to store the calculated size in the database.
During the save process, the file size is extracted in bytes, converted to kilobytes, and saved as part of the model.
This allows the application to quickly display file sizes and monitor storage usage for each student.
Limiting Storage Usage
One important design decision was limiting the number of resumes a student can upload.
Without restrictions, a user could continue uploading files indefinitely, consuming unnecessary server storage.
For the MVP, I decided to allow a maximum of 10 resumes per student.
This limit keeps storage predictable while still giving students the flexibility to maintain multiple versions of their resumes.
If the business requirements change later, this limit can easily be adjusted.
Choosing clean() Over save()
Initially, I implemented the validation inside the model's save() method.
While experimenting, I found that this approach resulted in internal server errors when validation failed.
I moved the validation logic into Django's clean() method instead.
Now, the workflow is:
- Validate suspicious or restricted fields.
- Raise validation errors if necessary.
- Save the model only after all validations succeed.
This keeps validation separate from persistence and aligns better with Django's validation lifecycle.
Testing Through Django Admin
Before exposing the feature through REST APIs, I tested the complete workflow using the Django Admin interface.
This allowed me to verify:
- Resume uploads
- File size calculation
- Resume count validation
- Database updates
Using the admin panel first helped validate the business logic before integrating it into the frontend.
What's Next?
The next milestone is integrating Resume Management into the application workflow.
Instead of requiring students to upload a resume every time they apply for a job, they will be able to:
- Upload a new resume, or
- Select one they've already uploaded
This mirrors the experience provided by professional job platforms while reducing duplicate uploads and unnecessary storage.
Final Thoughts
Building a Resume Management module reminded me that file uploads aren't just about accepting documents.
They're about designing storage policies, validating user input, and creating a system that remains manageable as the number of users grows.
Sometimes the real engineering challenge isn't storing a file—it's deciding how that storage should scale over time.
I'm documenting every engineering decision while building this Placement Portal in public.