Django Basic Search
In this tutorial we will implement basic search in a Django website models.py
#models.py
from django.db import models
class Book(models.Model):
FANTASY = 1
MYSTERY = 2
ROMANCE = 3
BOOK_TYPES = (
(FANTASY, 'Fantasy'),
(MYSTERY, 'Mystery'),
(ROMANCE, 'Romance'),
)
title = models.CharField(max_length=50)
publication_date = models.DateField(null=True)
author = models.CharField(max_length=30, blank=True)
price = models.DecimalField(max_digits=5, decimal_places=2)
pages = models.IntegerField(blank=True, null=True)
book_type = models.PositiveSmallIntegerField(choices=BOOK_TYPES)
def __str__(self):
return self.title
class Meta:
db_table = 'books'
admin.py
#admin.py
from django.contrib import admin
from myapp.models import Book
class BookAdmin(admin.ModelAdmin):
list_display = ['title', 'publication_date', 'author', 'price', 'book_type']
admin.site.register(Book, BookAdmin)
urls.py
#urls.py
from django.contrib import admin
from django.urls import path
from myapp import views
from django.conf.urls import url
from myapp.views import HomePageView, SearchResultsView
urlpatterns = [
path('admin/', admin.site.urls),
path('search/', SearchResultsView.as_view(), name='search_results'),
path('', HomePageView.as_view(), name='home'),
]
views.py
#views.py
from django.shortcuts import render, redirect
from django.views.generic import TemplateView, ListView
from myapp.models import Book
from django.db.models import Q
class HomePageView(TemplateView):
template_name = 'home.html'
# class SearchResultsView(ListView):
# model = Book
# template_name = 'search_results.html'
class SearchResultsView(ListView):
model = Book
template_name = 'search_results.html'
#queryset = Book.objects.filter(title__icontains='The Hobbit')
#def get_queryset(self): # new
# return Book.objects.filter(title__icontains='The Hobbit')
# def get_queryset(self):
# return Book.objects.filter(
# Q(title__icontains='The Hobbit') | Q(author__icontains='Cairocoders Ednalan')
# )
def get_queryset(self):
query = self.request.GET.get('q')
object_list = Book.objects.filter(
Q(title__icontains=query) | Q(author__icontains=query)
)
return object_list
templates/home.html
//templates/home.html
{% extends 'base.html' %}
{% block title %}Home {% endblock %}
{% block content %}
<h2>Django Search</h2>
<form action="{% url 'search_results' %}" method="get">
<p><input name="q" type="text" placeholder="Search..." class="form-control"></p>
<p><button type="submit" class="btn btn-success">Submit</button></p>
</form>
{% endblock %}
templates/base.html
//templates/base.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" name="viewport" content="width=device-width, initial-scale=1"/>
<title>{% block title %}Django Search {% endblock %}</title>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.5.0/css/bootstrap.min.css" integrity="sha384-9aIt2nRpC12Uk9gS9baDl411NQApFmC26EwAOH8WgZl5MYYxFfc+NcPb1dKGj7Sk" crossorigin="anonymous">
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="{% url 'home' %}">Cairocoders</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarNavAltMarkup" aria-controls="navbarNavAltMarkup" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNavAltMarkup">
<div class="navbar-nav">
<a class="nav-item nav-link active" href="">Home</a>
</div>
</div>
</nav>
<div class="container" style="padding:20px;">
<div class="col-md-12 well">
<h3 class="text-primary">Django Basic Search</h3>
<hr style="border-top:1px dotted #ccc;"/>
{% block content %} {% endblock %}
</div>
</div>
</body>
</html>
templates/search_results.html
//templates/search_results.html
{% extends 'base.html' %}
{% block title %}Search Result {% endblock %}
{% block content %}
<h3>Search Results</h3>
<ul>
{% for books in object_list %}
<li>
{{ books.title }}, {{ books.author }}
</li>
{% endfor %}
</ul>
{% endblock %}
