Build a Job Search Portal with Django — Part 1
By: Kumar Shubham
Tags: Programming, Bycetutorial, Django Framework, Django, Python

Build a Job Search Portal with Django — Overview (Part 1)

Let’s build a job search portal using Django which allows recruiters to post jobs and accept candidates while candidates search for jobs. Kumar Shubham Dec 7, 2020·8 min read

Photo by Andrew Neel on Unsplash

Hello readers! Hopefully, all of you would have read my five-part series on building a social media website using Django Framework. That series was well received and people loved reading it as it helped people build something practical and more complicated than simple tutorials. If you have not read that series till now, you can go and read them here:-

So, after the success of that series, I am starting one more series which will help people to build a job search portal using the Django framework. This series would be longer than the social media series and would have many new concepts. We would be handling both recruiters and candidates side so it gets a little large. Also, this time, we will implement a social login feature instead of regular email and password login. So, let’s begin.

The preliminary steps would be the same as in social media series. We create a project named fenice in this tutorial series. Then we create three more apps within the project candidates, recruiters and users.

The GitHub repository for this project can be found here. The repository I linked has requirements.txt file which lists out the dependencies and libraries we need to install to build this job search portal.

We also create a templates/socialaccount folder to overwrite some of the default pages which come with django-allauth which we are going to use for all our social login purposes for this project.

Installation and setup of django-allauth are mentioned in a very simple and friendly way on its official docs page. Go there and then follow the steps to use it to set up social login via Django.

In this project, we are using three social login methods for our users — Google, LinkedIn and GitHub.

You would need to create accounts on all of these providers to access the OAuth API which is used here. Follow the steps as mentioned in the official tutorial of django-allauth.

If you have any problems setting up social logins, this amazing article by Zoe Chew explains social login via django-allauth in a very easy and intuitive way. The author details each step while doing it for Google login. You need to follow similar steps for all three providers we are using here.

Now, those who are new to Django, you will have a little difficulty in getting this. To understand various terms and parameters in Django, its official documentation is the best place to go to.

Also, I am skipping some parts here which I already covered in the last series — Social Media Website with Django. So, if you have any problems in following with this, please refer to the last series.

After you have followed all the steps to set up a Django project you would end up with a folder structure as follows:-

Folders inside the project level fenice folder

The Procfile and .gitignore files are not required for now. The Procfile is required only when we want to host it on the internet. I was hosting it on Digital Ocean.

.gitignore is required to tell the host which files to ignore while uploading on the server.

And as you can see candidates, recruiters and users are three apps we built inside it. To do so, you need to follow the same command we use to create a Django app.

python manage.py startapp candidates

The command mentioned above will create an app. You can create all three apps, in the same way, changing the name of the app each time.

Now, let’s have a look at the settings.py file in the fenice folder.

We have various things added in our INSTALLED_APPS part. We are using:-

crispy_forms — for making our Django forms styled with Bootstrap 4 automatically. django-countries — for choosing a country from where the user belongs to. storages — it is used for using any cloud storage service. We are using DigitalOcean Cloud Storage here.

Next, we have added all the three apps which we have created: recruiters, candidates and users.

Then, we have all the allauth dependencies and we have three social providers which we need as our social login providers. So, we include them in the installed apps section.

INSTALLED_APPS = [

'django.contrib.admin',

'django.contrib.auth',

'django.contrib.contenttypes',

'django.contrib.sessions',

'django.contrib.messages',

'django.contrib.staticfiles',

'crispy_forms',

'django_filters',

'django_countries',

'users',

'recruiters',

'candidates',

'django.contrib.sites',

'allauth',

'allauth.account',

'allauth.socialaccount',

'allauth.socialaccount.providers.google',

'allauth.socialaccount.providers.linkedin_oauth2',

'allauth.socialaccount.providers.github',

'django_cleanup.apps.CleanupConfig',

'storages',

]

Next, we have all the usual Django stuff with no changes in them. Then we move to the Database option.

We are here using two different databases for debugging and production. For debugging purpose we are using the default SQLite database, but for production purpose, we are using a DigitalOcean Managed Database (PostgreSQL).

# Development Database

if (os.environ.get('DJANGO_DEV') == 'True'):

DATABASES = {

'default': {

'ENGINE': 'django.db.backends.sqlite3',

'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),

}

} # Production database

else:

DATABASES = {

'default': {

'ENGINE': 'django.db.backends.postgresql_psycopg2',

'NAME': 'defaultdb',

'USER': 'doadmin',

'PASSWORD': os.environ.get('DATABASE_PASSWORD'),

'HOST': 'fenice-database-do-user-8082982-0.b.db.ondigitalocean.com',

'PORT': '25060',

}

}

It is always a good idea to separate your debug and production database since we do not want our tests to interfere with our actual userbase. Also, using SQLite as a production database is not a good idea since it is not good for concurrency and has various limitations. But, it is actually a very good choice for the testing purpose since it comes built-in with Python and is very easy to set up.

Next, we set up CRISPY_TEMPLATE_PACK to be bootstrap4 since we want our forms to be stylized with bootstrap4 theme rather than bootstrap3 which it uses if we do not specify this line.

We then set up the LOGIN_URL to be ‘login’ which would serve as the URL which we use to access the login page. In our case, it would look something like localhost:8000/login since we defined it to use ‘login’ after the main URL.

Then we also defined the LOGIN_REDIRECT_URL to be ‘/’. It is the URL which we want users to redirect to after they are successfully logged in to our website. We have only provided a ‘/’ since we want users to be directed to our home page which would look like this: localhost:8000.

Also, we define a SITE_ID which is used to identify while setting up social login in our admin panel which can be accessed by using localhost:8000/admin and following the steps mentioned in that article which I linked earlier.

CRISPY_TEMPLATE_PACK = 'bootstrap4'



LOGIN_URL = 'login'

SITE_ID = 2

LOGIN_REDIRECT_URL = '/'

Next, we have SOCIALACCOUNT_PROVIDERS part. We have defined google, Linkedin and GitHub as we want these to be in our website as social providers. This part is used to define the scopes and parameters of these social providers. This can be done by following the steps mentioned in allauth.

We turn on the email querying to True as we want to have access to the email ids of all the users who are logging in. We need to do this since few providers won’t give access to mails if we don’t turn this to True.

SOCIALACCOUNT_PROVIDERS = {

'google': {

'SCOPE': [

'profile',

'email',

],

'AUTH_PARAMS': {

'access_type': 'online',

}

},

'linkedin': {

'SCOPE': [

'r_basicprofile',

'r_emailaddress',

],

'PROFILE_FIELDS': [

'id',

'first-name',

'last-name',

'email-address',

'picture-url',

'public-profile-url',

]

},

'github': {

'SCOPE': [

'user',

'repo',

'read:org',

],

}

}

SOCIALACCOUNT_QUERY_EMAIL = True

Then we define the DEFAULT_FILE_STORAGE in our file. We are here using Digital Ocean Spaces for the storage purpose.

We also have all the variables defined for the Digital Ocean Spaces Storage. (We do not need to indulge into it now).

We also need to define the STATIC_URL and STATIC_ROOT to define the location of storage of static files. Also, we define the same for MEDIA_URL and MEDIA_ROOT to define where we want to store the media files. We are using Digital Ocean Spaces for all these purposes.

STATIC_URL = '{}/{}/'.format(AWS_S3_ENDPOINT_URL, 'static')

STATIC_ROOT = 'static/'



MEDIA_URL = '{}/{}/'.format(AWS_S3_ENDPOINT_URL, 'media')

MEDIA_ROOT = 'media/'

Here is the complete settings.py file below:-

Hopefully, you understood it all right. Our next target would be to move to users and templates/socialaccount folder.

Next parts of this tutorial are:-

We would deal with those mentioned above in the second part of the tutorial. Then in the third and fourth part, we would deal with the logic part (views, models, forms, URLs) and templates part of the candidates' app respectively.

And lastly, in the fifth and sixth part, we would deal with the logic part (views, models, forms, URLs) and templates part of the recruiters’ app respectively.

So, hopefully, you would have liked this tutorial series idea and would be excited for the future parts where the real action unfolds. This was just an overview and set up of the project. Hope you all are excited!

Some more stories to read:-