You can download the source code for this tutorial here.
We’ve covered everything we need to know to create a simple Django application. In this article, we’ll add some optional features for our website, including paginator, related posts, search function and user authentication with django-allauth. If you are not interested, just skip to the end of this article and start preparing for deployment.
When we add more and more posts to our blog, creating a paginator might be a good idea, since we don’t want to have too many posts on one page. To do that, we need to add some extra code to our views. Let’s take the
home view as an example. First, we need to import some necessary packages:
Here I stripped away the unchanged codes to avoid confusion, but you need to remember to add them.
From line 9 to 14, here we need to consider three different conditions. If the page number is an integer, if the page number is not an integer, and if the page number is empty.
Next, we need to display the paginator in the template like this:
Refresh the page and you should see the paginator at the bottom.
You should do the same for all the pages that contain a list of posts.
The idea is to get the posts with the same tags.
This code is a little difficult to understand, but don’t worry, let’s analyze it line by line.
Line 2, get the requested post using the
Line 8, get all the tags that are related to the requested post.
Line 10, this is where things get tricky. First,
Post.objects.all() retrieves all posts from the database. And then,
filter(tag__in=post_tags) retrieves all posts that have tags which are related to the current post. However, we have two problems. The current post will also be included in the query set, so we use the
exclude(id=requested_post.id) to exclude the current post.
The second problem, however, is not that easy to understand. Let’s consider this scenario. Here we have three posts and three tags.
|Tag ID||Tag Name|
|Post ID||Post Name|
And the posts and tags have a many-to-many relationship with each other.
|Tag ID||Post ID|
|Post ID||Tag ID|
Let’s say our current post is post
2, that means our related tags will be
3. Now, when you are using
filter(tag__in=post_tags), Django will first go to tag
1, find tag
1’s related posts, which is post
1, and then go to tag
2, find tag
2’s posts, and finally move onto tag
3. That means
filter(tag__in=post_tags) will eventually return
[2,3,1,1,2,3,2]. After the
exclude() method, it would return
[3,1,1,3]. This is still not what we want, we need to find a way to get rid of the duplicates.
This is why we need to use
values_list('id') to pass the post
ids to the variable
related_posts_ids and then use that variable to retrieve the related posts. This way will eliminate the duplicates.
Finally, we can display the related posts in the corresponding template:
Next, we can add a search function for our app. To create a search function, we need a search form in the frontend, which will send the search query to the view, and the view function will retrieve the qualified records from the database, and finally return a search page that will display the result.
First, let’s add a search form into our sidebar:
Line 7-8, adds
name attribute to the
input field, its value could be anything, here we’ll call it
When the button is clicked, it’ll go to the URL with the name
'search', so we need to register the corresponding URL pattern.
User authentication is a very important part in web development, and it is not as easy as it seems. You have to consider different scenarios, for example, what if the user forgets the password, what if the user lost the email account, and how do you verify the user’s information, etc.
With Django, there are two different ways we can build a user authentication system. This first one is by using Django’s built-in
auth module. This method is the standard, but it is relatively complicated. You have to create the views and templates on your own. I’ll create another tutorial on this subject, for now you can use this article for reference if you are interested in this method.
Finally, it’s time to deploy our Django project. Instead of doing everything manually, we use a server management panel, which is much more beginner-friendly. There are a few things we need to do before deploying our website. First, we need to prepare the static and media files. Make sure you have the following code in your
Run the following command:
This command will collect all static files from all the apps you created into the
The media files, on the other hand, Django discourages serving media files directly from the server in the production environment. You need to configure your server settings. Take Apache as an example:
/media/ matches the setting for
/path/to/media/ is the absolute path to the
Run Deployment Check
Before we deploy our project, we need to check a few things. Go to terminal and run
manage.py check --deploy. This command will check the
ALLOWED_HOSTS and a few other sensitive settings for you.
Please check your own settings against this documentation.
First, let’s set up a new VPS. I assume you already bought one from a cloud infrastructure provider such as DigitalOcean, Vultr or Linode. Now, you have two choices, you can either follow this tutorial and use a control panel to deploy our project, or you can do it manually.
The control panel method does not guarantee success, I choose to use it here because it is a lot easier for beginners. So if it does not work for you, please refer to this article and deploy it manually. There is a lot of different panels you can choose from. Here I’ll use aaPanel as an example. (aaPanel Demo)
Run the shellcode on the official site of aaPanel. Make sure you are running CentOS on your VPS. aaPanel is developed on CentOS, using other systems may cause errors. After the installation process is finished. Follow the instructions on the screen and log into the panel.
From now on, everything should be straightforward. Just install the latest version of the Apache server and Python. You can install MySQL if you want. It is more robust and secure. But if you don’t, Django will use SQLite by default. You can also install other tools, but for now, these are all we need.
We can use the Python Manager tool to deploy our Django project.
I tested this tool on my own server and it worked for me. However, since it is still under development, there is a chance that it won’t work for you. In that case, please refer to this post on how to deploy Django project manually.
First, go to “Files”, and create a new directory.
After that, upload your entire project to the folder you just created.
Next, open the Python Manager and add a new project.
“Path” should point to the dir that contains
manage.py. “Version” is the version of Python that you installed.
The startup module is can be either
uwsgi. They are both interfaces that allow Django and the webserver to communicate.
gunicorn did not work for me, so maybe you should try
The startup dir should point to the folder that contains
wsgi.py. And finally, the “Port” can be anything you want. Once you click confirm, it will take a few minutes to install all dependencies.
Finally, map the domain to the server and we are good to go!.