Open In App

Resume Uploader Project in Django Python

Last Updated : 13 Oct, 2023
Like Article

A Resume Uploader Django project is a web application that allows users to upload and view resumes. It’s a practical project that can be used for job portals, recruitment websites, or HR departments to collect and manage resumes from candidates. In this Django project, we will provide a step-by-step explanation of the code for each component, including views, models, forms, templates, and styling.

Resume Uploader Project in Django Python

To install Django follow these steps.

Setting up the Project

To start the project use this command

django-admin startproject resumeuploader
cd resumeuploader

To start the app use this command

python startapp myapp

Now add this app to the ‘’

File Structure


File structure

Setting up the Files The file defines the data models for the application. It represents how data is structured and stored in the database.

Resume Model

  • This model defines the fields for a resume, including candidate name, date of birth, gender, contact details, address, and attachments (profile image and resume document).
  • It uses various field types such as CharField, DateField, PositiveIntegerField, EmailField, ImageField, and FileField to store different types of data.

The state field uses choices to limit options to specific Indian states.


from django.db import models
    ('Andaman & Nicobar islands', 'Andaman & Nicobar islands'),
    ('Andhra Pradesh', 'Andhra Pradesh'),
    ('Arunachal Pradesh', 'Arunachal Pradesh'),
    ('Assam', 'Assam'),
    ('Bihar', 'Bihar'),
    ('Chandigarh', 'Chandigarh'),
    ('Chhattisgarh', 'Chhattisgarh'),
    ('Dadra & Nagar Haveli', 'Dadra & Nagar Haveli'),
    ('Daman & Diu', 'Daman & Diu'),
    ('Delhi', 'Delhi'),
    ('Goa', 'Goa'),
    ('Gujarat', 'Gujarat'),
    ('Haryana', 'Haryana'),
    ('Himachal Pradesh', 'Himachal Pradesh'),
    ('Jammu & Kashmir', 'Jammu & Kashmir'),
    ('Jharkhand', 'Jharkhand'),
    ('Karnataka', 'Karnataka'),
    ('Kerala', 'Kerala'),
    ('Lakshadweep', 'Lakshadweep'),
    ('Madhya Pradesh', 'Madhya Pradesh'),
    ('Maharashtra', 'Maharashtra'),
    ('Manipur', 'Manipur'),
    ('Meghalaya', 'Meghalaya'),
    ('Mizoram', 'Mizoram'),
    ('Nagaland', 'Nagaland'),
    ('Odisha', 'Odisha'),
    ('Puducherry', 'Puducherry'),
    ('Punjab', 'Punjab'),
    ('Rajasthan', 'Rajasthan'),
    ('Sikkim', 'Sikkim'),
    ('Tamil Nadu', 'Tamil Nadu'),
    ('Telangana', 'Telangana'),
    ('Tripura', 'Tripura'),
    ('Uttarakhand', 'Uttarakhand'),
    ('Uttar Pradesh', 'Uttar Pradesh'),
    ('West Bengal', 'West Bengal'),
class Resume(models.Model):
    name = models.CharField(max_length=100)
    dob = models.DateField(auto_now=False, auto_now_add=False)
    gender = models.CharField(max_length=100)
    locality = models.CharField(max_length=100)
    city = models.CharField(max_length=100)
    pin = models.PositiveIntegerField()
    state = models.CharField(choices=STATE_CHOICE, max_length=50)
    mobile = models.PositiveIntegerField()
    email = models.EmailField()
    job_city = models.CharField(max_length=50)
    profile_image = models.ImageField(upload_to='profileimg', blank=True)
    my_file = models.FileField(upload_to='doc', blank=True)

  • import Statements: The code imports necessary modules from Django and the application’s Resume model.
  • Constants: It defines two lists, GENDER_CHOICES and JOB_CITY_CHOICES, which provide options for gender and preferred job cities.
  • ResumeForm Class: This is a Django form for collecting user data. It includes fields for name, date of birth, gender, and more. Gender uses radio buttons, and preferred job cities use checkboxes.
  • Meta Class: This nested class sets metadata for the form, linking it to the Resume model and specifying form fields, labels, and widget attributes.
  • Field Definitions: The code defines various form fields like text inputs, date picker, and selects, specifying their attributes and styles.
  • Usage: This form is meant for a Django web application, allowing users to submit resume information, including personal details, gender, and preferred job locations, which are processed to create Resume model instances.


from django import forms
from .models import Resume
    ('Male', 'Male'),
    ('Female', 'Female')
    ('Delhi', 'Delhi'),
    ('Pune', 'Pune'),
    ('Ranchi', 'Ranchi'),
    ('Mumbai', 'Mumbai'),
    ('Dhanbad', 'Dhanbad'),
    ('Bangalore', 'Bangalore')
class ResumeForm(forms.ModelForm):
    gender = forms.ChoiceField(
        choices=GENDER_CHOICES, widget=forms.RadioSelect)
    job_city = forms.MultipleChoiceField(
        label='Preferred Job Locations',
    class Meta:
        model = Resume
        # Specify the fields to include in the form
        fields = ['name', 'dob', 'gender', 'locality', 'city',
                  'pin', 'state', 'mobile', 'email',
                  'job_city', 'profile_image', 'my_file'
        labels = {
            'name': 'Full Name',
            'dob': 'Date of Birth',
            'pin': 'Pin Code',
            'mobile': 'Mobile No.',
            'email': 'Email ID',
            'profile_image': 'Profile Image',
            'my_file': 'Document'
        widgets = {
            'name': forms.TextInput(attrs={'class': 'form-control'}),
            'dob': forms.DateInput(attrs={'class': 'form-control',
                                          'id': 'datepicker'}),
            'locality': forms.TextInput(attrs={'class': 'form-control'}),
            'city': forms.TextInput(attrs={'class': 'form-control'}),
            'pin': forms.NumberInput(attrs={'class': 'form-control'}),
            'state': forms.Select(attrs={'class': 'form-control'}),
            'mobile': forms.NumberInput(attrs={'class': 'form-control'}),
            'email': forms.EmailInput(attrs={'class': 'form-control'}),

The file is used to configure how the Django admin panel displays and interacts with the models.This admin class registers the Resume model and specifies the fields to be displayed in the admin panel.


from django.contrib import admin
from .models import Resume
class ResumeModelAdmin(admin.ModelAdmin):
    list_display = ['id', 'name', 'dob', 'gender', 'locality', 'city',
                    'pin','state', 'mobile', 'job_city', 'profile_image', 'my_file']

The file in the “myapp” app contains Python classes that define the behavior of various views in the project.

  • HomeView: This class-based view handles the home page of the application. In the get method, it renders the home page with an empty resume form and a list of candidates retrieved from the database. In the post method, it processes the form data when a user submits a resume. If the form is valid, it saves the resume and returns the home page.
  • CandidateView: This view displays detailed information about a specific candidate. In the get method, it retrieves and displays the candidate’s information based on their primary key.


from django.shortcuts import render
from .forms import ResumeForm
from .models import Resume
from django.views import View
class HomeView(View):
    def get(self, request):
        form = ResumeForm()
        candidates = Resume.objects.all()
        return render(request, 'myapp/home.html' , {'candidates': candidates , 'form':form})
    def post(self, request):
        form = ResumeForm(request.POST, request.FILES)
        if form.is_valid():
            return render(request, 'myapp/home.html' , {'form':form})
class CandidateView(View):
    def get(self, request, pk):
        candidate = Resume.objects.get(pk=pk)
        return render(request, 'myapp/candidate.html', {'candidate':candidate})

Add the below code in your file which will create the media folder in which your images and also the document will save automatically

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL = '/media/'

  • Admin Panel URL: The code sets up a URL pattern for accessing the Django admin panel at ‘admin/’.
  • Home Page URL: It defines a URL pattern for the home page (‘/’) that maps to the HomeView class-based view, allowing users to access the main page of the application.
  • Candidate Details URL: Another URL pattern is defined with a dynamic parameter ‘pk’ (representing the candidate’s primary key) that maps to the CandidateView view. This allows users to view details of a specific candidate by visiting a URL like ‘/1/’.
  • Static Media Files: If the project is in debug mode (settings.DEBUG is True), the code appends URL patterns for serving media files (e.g., uploaded images and documents) during development. This ensures that user-uploaded content is accessible.
  • Names for URL Patterns: Each URL pattern is given a name (e.g., ‘home’ and ‘candidate’) for easier reference in templates and views.


from django.contrib import admin
from django.urls import path, re_path
from django.conf import settings
from django.conf.urls.static import static
from myapp.views import HomeView
from myapp.views import CandidateView
urlpatterns = [
    path('', HomeView.as_view(), name='home'),
    path('<int:pk>', CandidateView.as_view(), name='candidate'),
if settings.DEBUG:
    urlpatterns += static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

Working on GUI


This HTML template is used for the home page.It displays a resume submission form, a list of candidates, and uses Bootstrap for styling.The form includes fields for personal information and resume attachment.It utilizes Django template tags to render form elements and candidate data.


<!DOCTYPE html>
{% load static %}
<html lang="en">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Resume Uploader</title>
    <!-- Latest compiled and minified CSS -->
    <!-- jQuery UI Datepicker CSS -->
    <!-- Custom CSS (assuming style.css is in the 'myapp' static directory) -->
    <link rel="stylesheet" href="{% static 'myapp/style.css' %}">
    <div class="container mb-5">
        <h1 class="alert alert-danger text-center p-3">Resume Uploader</h1>
        <div class="row">
            <div class="col-sm-8">
                <form action="" method="post" enctype="multipart/form-data" class="shadow p-5">
                    {% csrf_token %}
                    {% for field in form %}
                    <div class="form-group mb-3">
                        {{ field.label_tag }} {{ field }}
                        <small class="text-danger">{{ field.errors }}</small>
                    {% endfor %}
                    <input type="submit" value="Submit" class="btn btn-primary">
                    {% if form.non_field_errors %}
                    {% for error in form.non_field_errors %}
                    <p class="alert alert-danger my-3">{{ error }}</p>
                    {% endfor %}
                    {% endif %}
            <div class="col-sm-4">
                <h4 class="text-center mb-3"><u>List of Candidates</u></h4>
                {% for candidate in candidates %}
                {{}}: <a href="{% url 'candidate' %}">{{}}</a>
                {% endfor %}
    <!-- jQuery library (required for Bootstrap JavaScript plugins) -->
    <script src=""></script>
    <!-- jQuery UI Datepicker JS -->
    <script src=""></script>
    <!-- Popper.js (required for Bootstrap JavaScript plugins) -->
    <!-- Latest compiled and minified JavaScript -->
        $(function () {


This HTML template represents the candidate details page. The template dynamically populates candidate information using Django template tags. It displays the candidate’s name, date of birth, gender, address, mobile number, and email.


<!DOCTYPE html>
{% load myfilter %}
<html lang="en">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <!-- Latest compiled and minified CSS -->
    <div class="container">
        <h1 class="alert alert-danger text-center mt-4">Candidate Details</h1>
        <div class="row">
            <div class="col-sm-8 offset-sm-2 shadow p-5">
                <h3 class="text-center mb-4"><u>Resume</u></h3>
                <div class="row">
                    <div class="col-sm-4 text-center">
                        <img src="{{ candidate.profile_image.url }}" alt="" class="img-fluid img-thumbnail" width="150" height="150">
                    <div class="col-sm-8">
                        <p><strong>Name:</strong> {{ }}</p>
                        <p><strong>Date of Birth:</strong> {{ candidate.dob }}</p>
                        <p><strong>Gender:</strong> {{ candidate.gender }}</p>
                        <p><strong>Address:</strong> {{ candidate.locality }}, {{ }}, {{ candidate.state }}-{{ }}</p>
                        <p><strong>Mobile No:</strong> {{ }}</p>
                        <p><strong>Email ID:</strong> {{ }}</p>
                        <p><strong>Preferred Job Cities:</strong> {{ candidate.job_city|remove_special:"[]'"}}</p>
                        <p><strong>Attachment:</strong> <a href="{{ candidate.my_file.url }}" target="_blank">Download</a></p>
                        <div class="">
                            <a href="/" class="btn btn-danger">Back to Home</a>
    <!-- jQuery library (required for Bootstrap JavaScript plugins) -->
    <script src=""></script>
    <!-- Popper.js (required for Bootstrap JavaScript plugins) -->
    <!-- Latest compiled and minified JavaScript -->


we write the some css for making out web page attractive .


    list-style-type: none;
    display: inline-flex;
    list-style-type: none;
    display: inline-flex;
#id_gender > li{
    padding-left: 10px;
#id_job_city > li{
    padding-left: 10px;
    margin-top: 30%

Deployement of the Project

Run these commands to apply the migrations:

python3 makemigrations
python3 migrate

Run the server with the help of following command:

python3 runserver






Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads