How to create a simple blog using Django 3 - part 10

/ #Django

In this part of the series we're going to create a simple search for our blog. The search isn't that fancy, but it'll work.

Creating the search view

In order to show the search results, we need a view. We can just add it in the same view file as the other views we created earlier. So go ahead and open "blog/" in your editor.

# In the top of the file, import Q
from django.db.models import Q


def search(request):
	query = request.POST.get('query', '')
	posts = Post.objects.filter(Q(title__icontains=query) | Q(intro__icontains=query) | Q(body__icontains=query)).filter(status=Post.PUBLISHED)
	categories = Category.objects.all()
	context = {
		'posts': posts,
		'query': query,
		'categories': categories
	return render(request, 'blog/templates/search.html', context)

Q is a helper function from Django which helps us write a little bit more complicated QuerySets.

We created a new view called "Search". The most important part of the search view is the "posts" variable where we use the Q. We add a filter to get posts containing the query either in the title, the intro or the body. icontains means that it doesn't matter if it's a uppercase or a lowercase search.

Adding the template

Create a new file inside the folder "blog/templates" and call it "search.html". It's very similar to the category.html file, so you can copy it and just make some changes.

{% extends 'base.html' %}

{% block content %}
	<div class="container splitter">
		<div class="blog-list">
			<h1 class="title">Search</h1>
			<p>Query: "{{ query }}"</p>

			{% for post in posts %}
				<article class="post">
					<a href="{% url 'post_detail' post.slug %}">
						<h2 class="subtitle">{{ post.title }}</h2>

						<p class="info">
							<time datetime="{{ post.created_at|date:"y-m-d" }}">My name / {{ post.created_at|date:"M d, y" }}

						<p class="description">
							{{ post.intro }}
					<a href="{% url 'post_detail' post.slug %}" class="readmore">Read more</a>
			{% endfor %}
		<aside class="splitter-aside">
			<div class="search">
				<form method="post" action="/search/">
					{% csrf_token %}
					<div class="field has-addons">
						<div class="control">
							<input class="input" name="query" type="text" value="{{ query }}">
						<div class="control">
							<button class="button is-info">Search</button>
			<div class="categories">

					{% for category in categories %}
						<li><a href="{% url 'category' category.slug %}" title="{{ category.title }}">{{ category.title }}</a></li>
					{% endfor %}
{% endblock %}

Feel free to copy the "search" div in the sidebar to the other templates. This way, the search will show everywhere. In a later part of this tutorial, I'm going to show you how to make this part much better by including a template.

Adding the view to the urlpatterns

Open up "myblog/" and make the following changes:

# Import the search view
from blog.views import search

# Adding the view to the urlpatterns (Above the post detail)
path('/search/', search, name='search'),

Nice, that's it :-)

If you copied the search from and pasted it in all of the templates, you should now be able to go to your blog and try the search function.


We've now added search to our blog and most parts of the blog has been covered. But there are still a lot of optimizations that can be done. In the next part of this tutorial, I'm going to do some of them. Stay tuned :-)

How to create a simple blog using Django 3 series

Part 1 - Installation
Part 2 - File structure
Part 3 - Database models
Part 4 - Admin interface
Part 5 - Creating some templates
Part 6 - Views and URLs
Part 7 - Category views
Part 8 - Media files
Part 9 - Comments
Part 10 - Search


No comments yet...

Add comment

Subscribe to my newsletter