Django Search (with Q objects) Tutorial

Prerequisites

  • Get familiar with basic Django, and its structures
  • Get familiar with Bootstrap, and basic frontend programming languages , HTML, CSS.

How does search work ?(Brief)

Search form on Django documentation

4 Steps closer

  • We typed “admin” on this form to get desired admin results related to the word admin
  • q (String field) is sent to a Django server with a value “admin”
  • Django server receives q variable, and navigate to a database for seaching any posts related to, or contained with “admin
  • Then send posts back to a client showing all posts related to admin on a web page

Look at this url → search/?q=admin

Searching for “admin” then the list of admin displayed

Let’s get started

Create Django project

django-admin startproject myproject
python manage.py startapp myapp

Let’s create our first Django model

from django.db import models# Create your models here.class Post(models.Model):    title = models.CharField(max_length=80)    content = models.TextField()    date_created = models.DateTimeField(auto_now_add=True)    date_updated = models.DateTimeField(auto_now=True)
def __str__(self): return self.title
INSTALLED_APPS = [    'myapp', # New    'django.contrib.admin',    'django.contrib.auth',    'django.contrib.contenttypes',    'django.contrib.sessions',    'django.contrib.messages',    'django.contrib.staticfiles',]
python manage.py makemigrations
Successfully make migrations
python manage.py migrate
Migrating to our database
SQLite database file was built

Create a superuser to access an admin site

python manage.py createsuperuser
Create superuser on terminal

Register a Django model

from django.contrib import adminfrom .models import Post  # New# Register your models here.admin.site.register(Post)  # New

Django Admin Site

Django administration
Django admin
Save and add other posts
Added 3 posts to test

Creating Django Templates

<!DOCTYPE html>
<head><title>Home</title></head>
<body> <h1>Hello Django</h1></body>

Django Render Template

from django.shortcuts import renderfrom .models import Post  # Create your views here.def index(request):
return render(request, 'myapp/index.html')

Django URL Routing

from django.urls import pathfrom . import viewsurlpatterns = [    path('', views.index, name="index")]
from django.contrib import adminfrom django.urls import path, include  # Newurlpatterns = [path('admin/', admin.site.urls),path('', include('myapp.urls'))  # New]
Home page

Integrating Bootstrap Navbar to our Django site

  • Add Bootstrap CDN
  • Add Bootstrap Navbar
Bootstrap CDN
Bootstrap Navbar
<!DOCTYPE html><head>    <!-- Boostrap CSS CDN -->    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/css/bootstrap.min.css" integrity="sha384-TX8t27EcRE3e/ihU7zmQxVncDAy5uIKz4rEkgIXeMed4M0jlfIDPvg6uqKI2xXr2" crossorigin="anonymous">    <title>Home</title></head>
<body><!-- Boostrap Navbar --><nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>

<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropdown
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</li>
<li class="nav-item">
<a class="nav-link disabled" href="#" tabindex="-1" aria-disabled="true">Disabled</a>
</li>
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
</nav>
<!-- Our content --> <h1>Hello Django</h1> <!-- Boostrap JS CDN --> <script src="https://code.jquery.com/jquery-3.5.1.slim.min.js" integrity="sha384-DfXdz2htPH0lsSSs5nCTpuj/zy4C+OGpamoFVy38MVBnE+IbbVYUew+OrCXaRkfj" crossorigin="anonymous"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@4.5.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-ho+j7jyWK8fNQe+A12Hb8AhRq26LrZ/JpcUGGOn+Y7RsweNrtN/tE3MoK7ZeZDyx" crossorigin="anonymous"></script>
</body>
Home page with Bootstrap Navbar

Django QuerySet(Query data from a database)

from django.shortcuts import renderfrom .models import Post  # New# Create your views here.def index(request):
# Query all posts posts = Post.objects.all()
return render(request, 'myapp/index.html', {'posts': posts})
<div class="container">    <h1>Hello Django</h1><br>    {% for post in posts %}    <h1>{{forloop.counter}}. {{post.title}}</h1>    <p>{{post.content}}</p>    <p>Date Created: {{post.date_created}}</p>    <p>Last Update: {{post.date_updated}}</p>    {% endfor %}</div>
Posts list

Descending order of our posts

posts = Post.objects.all().order_by("-date_created")
The lastest post will be on top of the page orderly

Implementing Django Search with Bootstrap form

Test seaching

Adding search string parameter and url endpoint to search for

  • adding search string parameter called “search”
name="search"
  • Add url endpoint to an action attribute of form after submitting a form
action="{% url 'index' %}"
<form class="form-inline my-2 my-lg-0" action="{% url 'index' %}">    <input class="form-control mr-sm-2" type="search"   placeholder="Search" aria-label="Search" name="search">    <button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button></form>
Bootstrap navbar search form
Test searching

Search with Q objects

  • Use & (AND) operator to search for more than 2 fields. For example, when searching title & content, both should be true, when searching for a word such as “python”, so it(python) should be contained in both title and content fields
  • Use | (OR) operator to search for only one field. For example, when searching title | content, both don’t have to be true, only one is okay, when searching for a word such as “python”, so it(python) doesn’t have to be contained in both title and content fields
from django.shortcuts import renderfrom .models import Postfrom django.db.models import Q  # New
search_post = request.GET.get('search')
if search_post:    posts = Post.objects.filter(Q(title__icontains=search_post) & Q(content__icontains=search_post)else:    # If not searched, return default posts    posts = Post.objects.all().order_by("-date_created")
views.py
Post found
Not found
Not found

Congratulations !! you just finished implementing a search form to search posts from a database

Conclusions

  • How search works
  • Basic Django MTV
  • Understanding Q objects
  • How to implement our existing search form with Django Q objects

If this article is helpful, please clap to support me continuing my good work, and do not hesitate to drop your comment below sharing me your opinion or problem. See you again next article.

Follow me on

--

--

--

Full Stack Python Developers

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

What is OpenTelemetry?

Understand *args And **kwargs in Python

WordPress Deployment on AWS EC2 and AWS RDS

AWS DynamoDB: Single or Multitable

Intro to x86–64: TryHackMe Room Walkthrough

Divide and Conquer

Developers’ Experience with Ron Barabash

Hasura + Heroku + Firebase — Firebase Authentication and Hasura Authorization to an iOS app

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
stackpython

stackpython

Full Stack Python Developers

More from Medium

Virtual environment set up for Django Application

Uploading images in Django Backend

Create Auth & Crud With Django

Simple REST API application using Flask