← All tutorials

Database / 7 MIN READ

Add a simple search box to your notes

Search titles and body text with Q objects and a shareable GET request.

01 Start with some notes

Use the Note model from the ORM tutorial and create a few records in the admin. A GET parameter is a good fit for read-only search because the resulting URL can be bookmarked.

02 Filter the QuerySet

Add this view to core/views.py. Q combines the two case-insensitive lookups with OR. The ORM handles query parameters; do not build SQL strings from the search input. Limiting results keeps this small example bounded.

Code example
from django.db.models import Q
from django.shortcuts import render
from .models import Note


def note_search(request):
    query = request.GET.get("q", "").strip()[:200]
    notes = Note.objects.order_by("-created_at")
    if query:
        notes = notes.filter(Q(title__icontains=query) | Q(body__icontains=query))
    return render(request, "core/search.html", {"notes": notes[:50], "query": query})

03 Create a search template

Save this as core/templates/core/search.html. The submitted search term remains visible, and the empty branch explains when there are no results.

Code example
{% extends "core/base.html" %}
{% block content %}
<h1>Search notes</h1>
<form method="get">
  <label for="q">Search</label>
  <input id="q" name="q" value="{{ query }}">
  <button>Search</button>
</form>
{% for note in notes %}
  <article><h2>{{ note.title }}</h2><p>{{ note.body }}</p></article>
{% empty %}
  <p>No matching notes. Try another word.</p>
{% endfor %}
{% endblock %}

04 Wire it up

Import note_search in config/urls.py and add this route. Visit /search/?q=django and try a word that appears only in a note's body. This example searches shared notes; an application with private notes must also filter by the current user's ownership.

Code example
path("search/", note_search, name="note_search"),
Keep exploring

Read the official Django documentation for details and more examples.