Python

How to Build a Basic Search for a Django Site?

A particular content of any site is normally retrieved by the users through Google search. However, if this search option is implemented on the website, then the users can easily find their desired content within the site without using Google search. . Another benefit of adding a search option within a website is that the developer can manage the searching output properly. That means he can control which content of the site will appear or not. This tutorial will show the process of implementing the basic search in the Django site.

Prerequisites:

Before practicing the script of this tutorial, you have to complete the following tasks:

  1. Install the Django version 3+ on Ubuntu 20+ (preferably)
  2. Create a Django project
  3. Run the Django server to check the server is working properly or not.

Setup a Django App:

Run the following command to create a Django app named searchapp.

$ python3 manage.py startapp searchapp

Run the following command to create the user for accessing the Django database. If you have created the user before then you don’t need to run the command.

$ python3 manage.py createsuperuser

Add the app name in the INSTALLED_APP part of the settings.py file.

INSTALLED_APPS = [

    …..

    'searchapp'

]

Create a folder named templates inside the searchapp folder and set the template’s location of the app in the TEMPLATES part of the settings.py file.

TEMPLATES = [

    {

….

                'DIRS': ['/home/fahmida/django_pro/searchapp/templates'],

                   ….

      },

]

Create Models:

Modify the models.py file with the following script. Here, two classes have been defined to create two relational tables named booktypes and books. The type field of the books table is a foreign key that will appear from booktypes table.

models.py

# Import necessary modules
from django.db import models
from django.urls import  reverse

# Create model gor booktype
class Booktype(models.Model):
    btype = models.CharField(max_length=100, unique=True)

    class Meta:
        ordering=('btype',)

# Create model gor book
class Book(models.Model):
    book_name = models.CharField(max_length=150)
    author_name = models.CharField(max_length=150)
    type = models.ForeignKey(Booktype, on_delete=models.CASCADE)
    price = models.FloatField()
    publication = models.CharField(max_length=100)

    class Meta:
        ordering=('book_name',)

    def __str__(self):
        return self.book_name

    def get_url(self):
       return reverse('book_detail', args=[self.id])

Create Templates for Searching:

Three HTML files are required for you to create the search feature shown in this tutorial. These are book_list.html, book_detail.html, and search.html. The book_list.html will display all records from the books table. The book_detail.html will display the details of a particular book. The search.html will display the search result after submitting the search form.

book_list.html

<html>
<head>
    <title>Book List</title>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>

<body>
<div class="container">
<div>
    <br/>
    <form action="{% url 'search' %}" class="form-inline" method="get">
       <div class="form-group mb-8">
            <h1>{% if type %}{{ type.name }}{% else %} List of Books {% endif %}</h1>
       </div>
       <div class="form-group mx-sm-3 mb-2">
        <label for="" class="sr-only">search</label>
        <input name="search" type="" class="form-control" id="" placeholder="Keyword">
        </div>
        <button type="submit" class="btn btn-success btn-lg mb-2">Search</button>
   </form>
        <br/>
    {% for x in book %}
    <h3> <a href="{{ x.get_url }}">{{x.book_name}}</a></h3>
    <p class="lead">by {{x.author_name}}</p>
      <p class="lead">${{x.price}}</p>
     <hr>
    {% endfor %}
</div>
</div>
</body>
</html>

book_detail.html

<html>
  <head>
  <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
    <title>{{book.book_name}}</title>
</head>
<body>
<div class="container">
    <br/><br/>
    <h2 class="text-center"> {{book.book_name}}</h2>
     <hr>
     <p class="lead">Author: {{book.author_name}} </p>
     <p class="lead">Type: {{type}} </p>
     <p class="lead">Publication: {{book.publication}} </p>
     <p class="lead">Price: ${{book.price}} </p>
     <form action="{% url 'book_list' %}" class="form-inline" method="get">
     <button type="submit" class="btn btn-primary btn-lg mb-2">Back</button>
     </form>
  </div>
  </body>
</html>

search.html

<html>
<head>
   <title>Search Result</title>
   <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
   <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
</head>
<body>
<br/></br/>
<div class="container">
   <div class="col-md-8 offset-md-2">
{% if query %}
           <h2>
           {% with results.count as total_results %}
           Found {{ total_results }} result{{ total_results|pluralize }}
           {% endwith %}
           </h2>
   {% for c in results %}
  <a href="{{c.get_url}}"><h3>{{c.book_name}}</h3></a>
  <h3>{{c.author_name}}</h3>

   {% empty %}
   <h3>No results found.</h3>
   {% endfor %}
  {% endif %}
        <form action="{% url 'book_list' %}" class="form-inline" method="get">
        <button type="submit" class="btn btn-primary btn-lg mb-2">Back</button>
        </form>
    </div>
</div>
</body>

<html>

Create View Functions:

Modify the views.py file with the following script. Three functions have been defined in the script. The book_list() function will display the book_list.html file. The book_detail() function will display the book_detail.html. The search() function will search the records based on the data submitted by the search form and display the result into the search.html.

views.py

# Import necessary modules
from django.shortcuts import render,get_object_or_404
from .models import  Book, Booktype
from django.db.models import Q

# Define function to display all books
def book_list(request):
    book = Book.objects.all()
    return render(request, 'book_list.html', {'book': book })

# Define function to display the particular book
def book_detail(request,id):
    book = get_object_or_404(Book, id=id)
    types = Booktype.objects.all()
    t = types.get(id=book.type.id)
    return render(request, 'book_detail.html', {'book': book, 'type': t.btype})

# Define function to search book
def search(request):
    results = []

    if request.method == "GET":
        query = request.GET.get('search')

        if query == '':
            query = 'None'

        results = Book.objects.filter(Q(book_name__icontains=query) | Q(author_name__icontains=query) | Q(price__icontains=query) )

    return render(request, 'search.html', {'query': query, 'results': results})

Set Paths to Call View Functions:

Modify the urls.py file of the Django project with the following script. Four paths have been defined in the script. ‘admin/’ path is used to open the Django Administrative Dashboard. The empty path(‘’) is used to call the book_list() function. ‘<int:id>/’ path is used to call the book_detail() function. ‘search/’ path is used to call the search() function.

urls.py

# Import admin module
from django.contrib import admin

# Import path module
from django.urls import path

# Import view
from searchapp import views

# Define paths
urlpatterns = [
     path('admin/', admin.site.urls),
     path('', views.book_list, name='book_list'),
     path('/', views.book_detail, name='book_detail'),
     path('search/', views.search, name='search'),
]

Run the App from the Browser:

Run the following command to run Django server.

$ python3 manage.py runserver

Run the following URL from any browser to display the list of the books from the table.

http://localhost:8000

If the user clicks on the link, “PHP and MySQL for Dynamic Web Sites” then the details of this book will appear in the browser.

If the user searches the word, physics in the browser then the following search result will display in the browser.

Conclusion:

A Django app with the basic search option has been implemented in this tutorial by using database tables. The new Django developers will be able to implement the search feature in their website after reading this tutorial.

About the author

Fahmida Yesmin

I am a trainer of web programming courses. I like to write article or tutorial on various IT topics. I have a YouTube channel where many types of tutorials based on Ubuntu, Windows, Word, Excel, WordPress, Magento, Laravel etc. are published: Tutorials4u Help.