Online Job Portal – Python Project with Source Code

Master Python with 70+ Hands-on Projects and Get Job-ready - Learn Python

Work on an intermediate level python django project – Online Job Portal in Python

The objective of this python project is to develop an online portal where recruiters can post job requirements, they can search for candidates. Candidates can search for job openings and apply.

Let’s look at some important points before starting

Users

  1. HR (employer)
  2. Job seeker (Student or employee)
  3. Admin

Job Portal Functionalities

  1. Login and Sign up for HR, not for Job seekers because there are a lot of websites where they would be applying, so logging in and remembering all usernames and passwords would be really hectic and why would we want that? So it is better to ask about their information when they actually apply for some company. But HR would have access to details of the job seekers, for which authorization is required.
  2. Listing of available jobs.
  3. Resume upload and apply to an organization.
  4. List of all candidates to the HR.

Data to be stored

For HR:

  1. Name of the organization.
  2. Position
  3. Job description
  4. Salary
  5. Location
  6. Experience

For Job seekers:

  1. Name
  2. DOB
  3. Gender
  4. Mobile
  5. Email
  6. Resume
  7. Organization name (the one on which he is applying)

Project Prerequisites

We will use the following technologies:

  • Python
  • HTML
  • CSS
  • Bootstrap
  • Django framework

To install the Django framework, type the following command on your console / terminal.

pip install Django

Download Python Job Portal Code

Please download the source code of job portal project: Job Portal in Python Django

Steps to develop the job portal project:

1. Writing Models

For storing the data we need to connect our server to a database, which models.py will handle.

Code

from django.db import models
from django.contrib.auth.models import User

# Create your models here.
class Company(models.Model):
    user=models.OneToOneField(User,null=True,on_delete=models.CASCADE)
    name=models.CharField(max_length=200,null=True)
    position=models.CharField(max_length=200,null=True)
    description=models.CharField(max_length=2000,null=True)
    salary=models.IntegerField(null=True)
    experience=models.IntegerField(null=True)
    Location=models.CharField(max_length=2000,null=True)

    def __str__(self):
        return self.name


class Candidates(models.Model):
    category=(
        ('Male','male'),
        ('Female','female'),
        ('Other','other'),
    )

    name=models.CharField(max_length=200,null=True)
    dob=models.DateField(null=True)
    gender= models.CharField(max_length=200,null=True,choices=category)
    mobile= models.CharField(max_length=200,null=True)
    email= models.CharField(max_length=200,null=True)
    resume=models.FileField(null=True)
    company=models.ManyToManyField(Company,blank=True)

    def __str__(self):
        return self.name

2. forms.py

Code

from django.forms import ModelForm
from .models import *

class ApplyForm(ModelForm):
    class Meta:
        model=Candidates
        fields="__all__"

Here, we are making an “apply form” for job seekers using Django’s ModelForm class.

3. admin.py

Code

from django.contrib import admin
from .models import *

# Register your models here.
admin.site.register(Company)
admin.site.register(Candidates)

We need to register the models on the admin site so that we can anytime create, update, or delete the model objects.

We also need a superuser who has complete access to all the information. To create a superuser:

Py manage.py createsuperuser

4. settings.py

Code

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

We will use FileField to upload resumes, so we need to configure MEDIA_URL in setting.py as it is not configured by default.

For this, we have to append the above code in settings.py. Also, we need to update the base urls.py file which is explained in the next step.

5. urls.py

Code

from django.contrib import admin
from django.urls import path,include
from django.conf import settings
from django.conf.urls.static import static

urlpatterns = [
    path('admin/', admin.site.urls),
    path('',include('JobPortal.urls'))
] + static(settings.MEDIA_URL,document_root=settings.MEDIA_ROOT)

JobPortal/urls.py:

Code

from django.urls import path
from .views import *

urlpatterns = [
    path('',home,name='home'),
    path('login/',loginUser,name='login'),
    path('logout/',logoutUser,name='logout'),
    path('register/',registerUser,name='register'),
    path('apply/',applyPage,name='apply'),
]

6. views.py

Code

from django.shortcuts import render,redirect
from .models import *
from django.contrib.auth.forms import UserCreationForm
from django.contrib.auth import login,logout,authenticate
from .forms import *

# Create your views here.
def home(request):
    if request.user.is_authenticated:
        candidates=Candidates.objects.filter(company__name=request.user.username)
        context={
            'candidates':candidates,
        }
        return render(request,'hr.html',context)
    else:
        companies=Company.objects.all()
        context={
            'companies':companies,
        }
        return render(request,'Jobseeker.html',context)


def logoutUser(request):
    logout(request)
    return redirect('login')


def loginUser(request):
    if request.user.is_authenticated:
        return redirect('home')
    else:
       if request.method=="POST":
        name=request.POST.get('username')
        pwd=request.POST.get('password')
        user=authenticate(request,username=name,password=pwd)

        if user is not None:
            login(request,user)
            return redirect('home')
       return render(request,'login.html')


def registerUser(request):
    if request.user.is_authenticated:
        return redirect('home')
    else:
        Form=UserCreationForm()
        if request.method=='POST':
            Form=UserCreationForm(request.POST)

            if Form.is_valid():
                currUser=Form.save()
                Company.objects.create(user=currUser,name=currUser.username)
                return redirect('login')
        context={
            'form':Form
        }
        return render(request,'register.html',context)


def applyPage(request):
    form=ApplyForm()
    if request.method=='POST':
        form=ApplyForm(request.POST,request.FILES)

        if form.is_valid():
            form.save()
            return redirect('home')
    context={'form':form}
    return render(request,'apply.html',context)

We have created five functions in this file:

1. Home: It performs the following functions:

If the user is authenticated (HR): It filters all the candidates, applied to HR’s organization, and passes them to the hr.html file, which displays all the candidates in tabular form and also provides an option to download their resumes.

Hr.html Code:

{% extends 'main.html' %}
{% load static%}

{% block content %}
<div class="container card">
    <h1>Candidates applied</h1>
    <div class="card-body">
        <table class="table table-hover">
            <tr>
                <th>Name</th>
                <th>DOB</th>
                <th>Resume</th>
                <th>Gender</th>
                <th>Mobile</th>
                <th>Email</th>
            </tr>
            {% for c in candidates %}
                <tr>
                    <td>{{c.name}}</td>
                    <td>{{c.dob}}</td>
                    {% if c.resume %}
                    <td><a href='{{c.resume.url}}' download >{{c.resume}}</td></a></td>
                    {% else %}
                    <td>Not submitted</td>
                    {% endif %}
                    <td>{{c.gender}}</td>
                    <td>{{c.mobile}}</td>
                    <td>{{c.email}}</td>
                </tr>
            {% endfor %}
        </table>
    </div>
</div>

{% endblock %}

If the user is not authenticated (Job Seeker): Then it passes all the company objects to Jobseeker.html which displays company details in a tabular form with an option to apply to that organization.

Jobseeker.html

{% extends 'main.html' %}
{% load static%}

{% block content %}
<div class="container card">
    <h1>Available openings</h1>
    <div class="card-body">
        <table class="table table-hover">
            <tr>
                <th>Name</th>
                <th>Position</th>
                <th>Description</th>
                <th>Salary</th>
                <th>Experience</th>
                <th>Location</th>
                <th>Join</th>
            </tr>
            {% for c in companies %}
                <tr>
                    <td>{{c.name}}</td>
                    <td>{{c.position}}</td>
                    <td>{{c.description}}</td>
                    <td>{{c.salary}}</td>
                    <td>{{c.experience}}</td>
                    <td>{{c.Location}}</td>
                    <td><a href="{% url 'apply' %}" class="btn btn-info btn-sm" type="submit">Apply</a></td>
                </tr>
            {% endfor %}
        </table>
    </div>
</div>
        {% for c in companies %}
            {{c.name}}
        {% endfor %}
{% endblock %}

Then there are logout, login, register functions that use Django’s inbuilt UserCreationForm, login, logout function.

Last function is Apply Page which enables Job seekers to apply for a job. It uses ApplyForm which we have already discussed in forms.py.

Apply.html

{% extends 'main.html' %}
{% load static%}

{% block content %}
<head>
    <style>
        .box{
            border:5px solid black;
        }
    </style>
</head>
<div class=" box jumbotron container">
    <form action="" method="POST" enctype="multipart/form-data">
        {% csrf_token %}
        {{form.as_p}}
        <input type="submit" class="btn btn-success btn-sm" value="submit">
    </form>
</div>
{% endblock %}

7. templates:

Make a ‘templates’ folder in the project folder to place all the frontend stuffs

login.html

{% extends 'main.html' %}
{% load static%}

{% block content %}
<head>
    <style>
        .maindiv{
            border:1px solid black;
        }
    </style>
</head>
<div class="maindiv jumbotron container ">

    <form method="POST" action="">
        {% csrf_token %}
        <p><input type="text" name="username" placeholder="Username..."></p>
        <p><input type="password" name="password" placeholder="Password..." ></p>
        <input class="btn btn-success" type="submit" value="Login">
        <p>Do not have an account<a href='{% url "register" %}'>Register</a></p>
    </form>

</div>
{% endblock %}

main.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous"0>
    <title>DataFlair Job portal Project</title>
</head>
<body>
    {% include 'navbar.html' %}
    <br>
    <br>
    {%block content%}
    
    {% endblock %}
</body>
</html>

navbar.html

<head>
    <style>
      .user{
        color:white;
        text-decoration: none;
      }
    </style>
  </head>
  <nav class="navbar navbar-expand-lg navbar-dark bg-dark">
      <a class="navbar-brand" href="{% url 'home' %}">HOME</a>
      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
        <span class="navbar-toggler-icon"></span>
      </button>
    
      <div class="collapse navbar-collapse" id="navbarSupportedContent">
      
        
      </div>
      {% if request.user.is_authenticated %}
      <span class="user">Hello, {{request.user}}  &nbsp;</span>
      <span ><a  class="user btn btn-info" href ="{% url 'logout' %}"> Logout</a></span>
      {% else %}
          <span ><a class="user" href="{% url 'login' %}">Login</a></span>>
          <span ><a class="user" href="{% url 'register' %}">Register</a></span>>
      {% endif  %}
    </nav>

register.html

{% extends 'main.html' %}
{% load static%}

{% block content %}
<head>
    <style>
        .maindiv{
            border:1px solid black;
        }
    </style>
</head>
<div class="maindiv jumbotron container">

    <form method="POST"  action="">
        {% csrf_token %}
        {{form.as_p}}
        <input class="btn btn-success btn-lg" type="submit" value="Register">
        <p>Already have an account<a href='{% url "login" %}'>Login</a></p>
    </form>

</div>
{% endblock %}

Job Portal Output

hr home page

job seeker home page

Summary

Thus, we have successfully completed the python django project, this is just a start to master python & django, keep working on projects, and gain expertise.

Happy Coding!

Did you like our efforts? If Yes, please give DataFlair 5 Stars on Google

courses

DataFlair Team

The DataFlair Team is passionate about delivering top-notch tutorials and resources on programming, Java, Python, C++, DSA, AI, ML, data Science, Android, Flutter, MERN, Web Development, and technology. With expertise in the tech industry, we simplify complex topics to help learners excel. Stay updated with our latest insights.

20 Responses

  1. kamran says:

    what is the database(mean which language )?

  2. smith says:

    6 Best Practices to Kick-Start Your Career after Graduation

  3. santosh premi adhikari says:

    thank you

  4. shami says:

    I think that is in python language.

  5. Priyanka Marathe says:

    How to access the database.

  6. Kavan Prajapati says:

    admin panel username and password?

  7. Sayon Islam says:

    The applied candidates details are not visible in the hr.html page… please help

  8. Sayon Islam says:

    The applied candidates details are not visible in the hr.html page..

    • Vaibhav Kalel says:

      The applied candidates details are not visible in the hr.html page and also when we resister for apply job it is reflected in the list of company page… so please help for this

  9. rutik says:

    How to change company name and description?

  10. Vaibhav Kalel says:

    The applied candidates details are not visible in the hr.html page and also when we resister for apply job it is reflected in the list of company page… so please help for this

  11. Raghu says:

    How to upload this file to public_html any guide ?

  12. Anuraj Singh says:

    So , I am using this project for my semester viva voca exam. Please anyone help me in understanding how this project is made , if there is any error in the project , and its related functions .
    Please, I need help my exam is next morning .

  13. sharmistha says:

    trustworthy website

    • HARIHARAN G says:

      Hey sharmistha, I am going to do this project on my final semester, I would really appreciate it if you could assist me. I look forward to hearing from you. Would you kindly respond to me?

Leave a Reply

Your email address will not be published. Required fields are marked *