liveBook · Manning

Q object

As explained in Django in Action

A Q object is a Django ORM expression object for composing complex query conditions with logical operators such as AND and OR.

A Q object builds a Django ORM query condition that can be combined before it reaches .filter(). Ordinary filter clauses are AND-ed together; Q objects let a search match either condition with |, or compound conditions with &. section 12.4

Search first or last names

Split a musician search into terms, make a Q condition for first_name__istartswith and another for last_name__istartswith, then join them with |. Add later terms to the same query and pass the finished condition to Musician.objects.filter(q). A search for several terms therefore finds a name beginning with any term. section 12.4

Listing 12.6 A search view for musicians by their names
# RiffMates/bands/views.py
...
from django.db.models import Q
...

def search_musicians(request):
    search_text = request.GET.get("search_text", "")  #1
    search_text = urllib.parse.unquote(search_text) #2
    search_text = search_text.strip()

    musicians = []

    if search_text:
        parts = search_text.split()  #3

        q = Q(first_name__istartswith=parts[0]) | \
            Q(last_name__istartswith=parts[0])  #4
        for part in parts[1:]: #5
            q |= Q(first_name__istartswith=part) | \
                Q(last_name__istartswith=part) #6

        musicians = Musician.objects.filter(q)  #7

    data = {
        "search_text": search_text,
        "musicians": musicians,
    }

    return render(request, "search_musicians.html", data)

The view shows the complete path from query-string text through whitespace parsing and Q composition to filtered musician results. section 12.4

How Django in Action covers it

How deep it goes
Explains Q arguments, | and & composition, and passing the finished condition to .filter(), without database internals.
Examples
Demonstrates a Musician first-name and last-name prefix search with multiple whitespace-separated terms.
What it assumes
Builds from familiar .filter() clauses and Python binary operators while introducing Q-based composition.
What you can do after
Apply it via the Django ORM to compose and run multi-condition search queries.
How it connects
Connects Q objects to Django ORM, QuerySet.filter(), HTMX, query parameters, and pagination.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Django in Action. The section links point to the parts of the book it draws on.