Building a Search Functionality - Django Blog #9

Hello Internet Programmers, hope you are enjoying this tutorial. Today we build a search functionality to search posts by some keywords. So, activate your virtual environment, and let’s do coding.

Complex lookups with Q objects

Using filter() is powerful and it’s even possible to chain filters together. However often you’ll want more complex lookups such as using “OR” which is when it’s time to turn to Q objects.

Open of blog application and make change in post_list view in as following,

from django.db.models import Q #import this at top

def post_list(request, tag_slug=None):

    # search
    query = request.GET.get("q")
    if query:
        posts=Post.published.filter(Q(title__icontains=query) | Q(tags__name__icontains=query)).distinct()

We added a query variable that takes the value of q from the form submission. q is name of input field we will see in template (just wait).

Then we filter to look for a result that matches a post title or post tags that contains whatever the keyword query variable have.

Search Form

Open base.html and edit search form like following,

<form class="d-flex" action="/">
          <input class="form-control mr-0" type="search" value="{{request.GET.q}}" name="q" placeholder="Search" aria-label="Search">

Here you notice name="q". When the user type “linux” as a query inside the search form then it’s looks like This captured in view as we have seen in the above code.

request.GET.q is returns the whatever we type in search box. So when user type the keyword and hit enter the same keyword again exist there, inside search box.

Also here I set action="/" means if the user wants to search from any page then form action submit to the home page and post_list view take place.

Also, add following code in base.html, inside main element,

<main class="container my-3">
        <!-- from here to -->
        <h2 class="my-3">
          {% if request.GET.q is not null %}
            Search Results for "{{ request.GET.q }}"
          {% endif %}
        <!-- here -->

        {% block content %}

        {% endblock content %}

Now run the development server using python3 runserver and open your blog and try to search something,

building a search functionality in django blog tutorial

search in django

Search result with pagination

Open pagination.html and edit the code like following,

{% if page.has_other_pages %}
  <ul class="pagination mt-3 mb-0">
    {% if page.has_previous %}
      <li class="page-item"><a class="page-link" href="?page={{ page.previous_page_number }}{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">&laquo;</a></li>
    {% else %}
      <li class="disabled page-item"><span class="page-link">&laquo;</span></li>
    {% endif %}
    {% for i in page.paginator.page_range %}
      {% if page.number == i %}
        <li class="active page-item"><span class="page-link">{{ i }}</span></li>
      {% else %}
        <li class="page-item"><a class="page-link" href="?page={{ i }}{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">{{ i }}</a></li>
      {% endif %}
    {% endfor %}
    {% if page.has_next %}
      <li class="page-item"><a class="page-link" href="?page={{ page.next_page_number }}{% if request.GET.q %}&q={{ request.GET.q }}{% endif %}">&raquo;</a></li>
    {% else %}
      <li class="disabled page-item"><span class="page-link">&raquo;</span></li>
    {% endif %}
{% endif %}

Here we added {% if request.GET.q %}&q={{ request.GET.q }}{% endif %}.

Means you also get result of that keyword, you type in search box in the next page.

search with pagination

search with pagination

This is simple search functionality in django. You can use a full-text search engine other than from PostgreSQL, Solr or Elasticsearch, you can integrate them into your Django project using Haystack. Haystack is a Django application that works as an abstraction layer for multiple search engines. It offers a simple search API that is very similar to Django QuerySets.

That’s it for this tutorial. Share it with your friends and stay awesome.

GitHub Link:

Previous: Retrieving Posts by Similarity – Django Blog #8

Next: Adding a Sitemap to the Website – Django Blog #10