Django Blog #34: Creating a Search View

by Alex
Django Blog #34: Creating a Search View
Now we need to create a view so that users can search for posts. The first thing you need is a search form. Edit the blog application’s forms.py file and add the following form:

class SearchForm(forms.Form) 
    query = forms.CharField()

We’ll use the query field so that users can enter search queries. Edit the views.py file and add the following code:

from django.contrib.postgres.search import SearchVector 
from .forms import EmailPostForm, CommentForm, SearchForm 

def post_search(request) 
    form = SearchForm() 
    query = None 
    results = [] 
   if 'query' in request.GET 
        form = SearchForm(request.GET) 
       if form.is_valid() 
            query = form.cleaned_data['query'] 
            results = Post.objects.annotate(
                search=SearchVector('title', 'body',) 
           ).filter(search=query) 
   return return(query, 
                 'blog/post/search.html', 
                 {'form': form, 
                   { 'query': query, 
                   { 'results': results})

In this view, the SearchForm instance is created first. It will be accepted using the GET method so that the resulting URL includes the query parameter. To check if the form is accepted, we check the query parameter in the request.GET dictionary. When the form is accepted, we create an instance of the form with the accepted GET data and verify it. If it passes verification, we search using SearchVector by the title and body fields. The search view is ready. You need to create a template for displaying the form and search results. Create a file in the templates folder /blog/post/, name it search.html, and add the following code:

{% extends "blog/base.html" %}

{% block title %}Search{% endblock %}

{% block content %}
  {% if query %}
    <h1>Posts containing "{{ query }}"</h1>
    <h3>
      {% with results.count as total_results %}
	Found {{ total_results }} result{{ total_results|pluralize }}
      {% endwith %}
    </h3>
    {% for post in results %}
      <h4><a href="{{ post.get_absolute_url }}">{{ post.title }}</a></h4>
      {{ post.body|truncatewords:5 }}
    {% empty %}
      <p>There are no results for your query.</p>
    {% endfor %}
    <p><a href="{% url "blog:post_search" %}">Search again</a></p>
  {% else %}
    <h1>Search for posts</h1>
    <form action="." method="get">
      {{ form.as_p }}
      <input type="submit" value="Search">
    </form>
  {% endif %}
{% endblock %}

As in the search view, you can tell if the form has been validated by the presence of the query parameter. Before checking, display the form and a confirmation button. After checking, display the search performed and the total number of results, as well as the list of posts. Finally, edit the blog application’s urls.py file and add the following URL template:

path('search/', views.post_search, name='post_search'),

Now open https://127.0.0.1:8000/blog/search/ in your browser. You will see a form. Enter the query and click on “Search”. The blog now has a basic search engine.

Related Posts

LEAVE A COMMENT