filter() asks a Django model’s query manager for a subset of database objects. Supply field lookups as keyword arguments; only objects whose fields match are included in the returned QuerySet. For example, first_name="John" selects every Musician whose first name is John—not merely the first result. section 4.4.1 section 4.12
A QuerySet is lazy: calling filter() builds up the underlying SQL without immediately fetching rows. Chain further filter() calls to narrow the result, then use an operation that needs data, such as first() or count(), to execute the query. Let the database search rather than fetching every object and sorting it in Python. section 4.4.1
Find musicians named John
Musician.objects.filter(first_name="John") returns a QuerySet containing the matching musicians. Store that QuerySet and call result.first() when one matching object is needed. The two steps keep the query focused and avoid treating a filtered collection as a single object. section 4.4.1
Lookups need not be exact. Add a double-underscore suffix to a field name to request another comparison, such as first_name__startswith="J" for names beginning with J. Django can also match substrings and compare numeric or date values through lookup arguments. section 4.12 section 4.4.1
Optional API name filter
An endpoint can begin with Venue.objects.all(), then apply venues.filter(name__istartswith=name) only when an optional name query parameter was supplied. The returned QuerySet becomes the endpoint’s list response, so the API does not need separate Python-side filtering. section 11.2.2
Listing 11.8 Venue object listing API end-point
# RiffMates/bands/api.py
...
@router.get("/venues/", response=list[VenueOut])
def venues(request, name=None): #1
venues = Venue.objects.all()
if name is not None:
venues = venues.filter(name__istartswith=name) #2
return venues
This endpoint shows the common pattern: start with all Venue objects, conditionally add an istartswith lookup, and return the resulting QuerySet. section 11.2.2
Do not confuse QuerySet filter() with Django template filters. Template filters use the pipe operator inside {{ variables }} to change displayed data, such as uppercasing text or formatting values; QuerySet filter() selects database rows before rendering or serialization. section 3.5.6 section 3.10
