Filtering, Getting and Chaining

Managers and querysets. Post.objects is the manager. Calling something on it returns a queryset, and querysets can be chained: Post.objects.filter(published=True).order_by("-created")[:10].

filter and get are not the same shape.

filter() returns a queryset, possibly empty. Asking for something that is not there is a normal outcome.

get() returns exactly one object, and raises otherwise: DoesNotExist when there is nothing, MultipleObjectsReturned when there is more than one.

In a view, use get_object_or_404. It is get() with the right behavior for the web already attached.

Lookups use a double underscore. title__icontains="sankofa", created__year=2026, views__gte=100, author__in=[a, b], slug__isnull=True.

It also follows relationships: Post.objects.filter(author__username="amara") filters posts by a field on the related user, in one query.

◈ Graded Challenge

Write query(posts, published=None, tag=None, order=None, limit=None) modeling what a chained queryset does, over a list of dictionaries. Each post has keys title, tag, published and views. When published is given, keep only posts whose published matches it. When tag is given, keep only posts with that tag. When order is "views" sort ascending by views; when it is "-views" sort descending. When limit is given, return at most that many. Return a list of titles, in the resulting order. Applying no options returns every title in the original order.

Name it exactly: query(posts, published=None, tag=None, order=None, limit=None)

Python4 visible + 4 hidden
loading editor…

Mark this lesson complete

Signed in, your progress follows you to every device.

Next: Laziness and the N+1 Problem →
← Back