python 37 lines · 7 steps

Filtering and paginating a Django product list

A view builds a lazy queryset step by step from URL parameters, then paginates it for the template.

Explained by highlit
1from django.core.paginator import Paginator
2from django.shortcuts import render
3 
4from .models import Product
5 
6 
7def product_list(request):
8 products = Product.objects.select_related("category").order_by("-created_at")
9 
10 category = request.GET.get("category")
11 if category:
12 products = products.filter(category__slug=category)
13 
14 search = request.GET.get("q", "").strip()
15 if search:
16 products = products.filter(name__icontains=search)
17 
18 in_stock = request.GET.get("in_stock")
19 if in_stock == "1":
20 products = products.filter(stock__gt=0)
21 
22 paginator = Paginator(products, 24)
23 page = paginator.get_page(request.GET.get("page"))
24 
25 querystring = request.GET.copy()
26 querystring.pop("page", None)
27 
28 return render(
29 request,
30 "catalog/product_list.html",
31 {
32 "page": page,
33 "querystring": querystring.urlencode(),
34 "category": category,
35 "search": search,
36 },
37 )
01 / 01
STEP 01

Walkthrough

Space play step click any line
Three takeaways
  1. 1Django querysets are lazy, so chaining filters conditionally builds no database work until the page is actually sliced.
  2. 2Reading filters straight from request.GET lets one view handle category, search, and stock combinations without extra routes.
  3. 3Stripping the page key from a copied querystring keeps pagination links carrying every other active filter.

Related explainers

Share this explainer

Here's the card — post it anywhere.

Filtering and paginating a Django product list — share card
Made with highlit — turn any snippet into a walkthrough like this in about a minute.
Explain your code