Filtering Pagination
title: "Filtering with Pagination — Applying Filters Across Pages" description: "Filtering with pagination applies consistent server-side filters across all pages, using query parameters that persist through pagination navigation." date: 2026-06-28 lastmod: 2026-06-28 weight: 18 tags: [apis, pagination] }
Filtering with pagination applies server-side filter criteria consistently across all pages, with filter parameters persisted in pagination links for stable navigation.
What You'll Learn
- Combining filters with pagination
- Filter parameter design
- Preserving filters in pagination links
Why It Matters
Filters must persist across paginated requests. If the filter changes between page 1 and page 2, the results are inconsistent.
Code Examples
# Filtering with pagination
@app.route('/users')
def list_users():
# Filters
status = request.args.get('status')
role = request.args.get('role')
search = request.args.get('q')
# Pagination
page = request.args.get('page', 1, type=int)
limit = min(request.args.get('limit', 20, type=int), 100)
# Build query
query = "SELECT * FROM users WHERE 1=1"
params = []
if status:
query += " AND status = ?"
params.append(status)
if role:
query += " AND role = ?"
params.append(role)
if search:
query += " AND (name LIKE ? OR email LIKE ?)"
params.extend([f"%{search}%", f"%{search}%"])
# Count
count = db.execute(f"SELECT COUNT(*) FROM ({query})", params)[0][0]
# Paginate
query += " ORDER BY id LIMIT ? OFFSET ?"
params.extend([limit, (page - 1) * limit])
users = db.execute(query, params)
# Build pagination links with preserved filters
def pagination_url(p):
qs = request.args.copy()
qs['page'] = p
return f"/users?{urlencode(qs)}"
return jsonify({
"data": users,
"pagination": {
"page": page,
"total": count,
"pages": (count + limit - 1) // limit,
"links": {
"first": pagination_url(1),
"next": pagination_url(page + 1) if page * limit < count else None,
"prev": pagination_url(page - 1) if page > 1 else None
}
}
})
Common Mistakes
1. Filters Not Applied to Count
Always apply the same filters to the count query and the data query.
2. Filter State Lost on Navigation
Pagination links must include current filter parameters.
3. Inconsistent Filter Parameter Names
Use consistent naming: status=active not filter[status]=active.
4. Case-Sensitive Filter Values
Use case-insensitive comparison for text filters.
5. Not Validating Filter Values
Validate filter values against allowed options before querying.
Practice Questions
- Why must filters be applied to both data and count queries?
- How do you preserve filters across pagination links?
- What is the risk of inconsistent filters between pages?
- How do you handle search queries with pagination?
- Why validate filter values?
Answers:
- Otherwise the count doesn't match the filtered results.
- Include current filter params in the pagination URL query string.
- Results shift between pages, causing duplicates or gaps.
- Apply the search LIKE clause to both count and data queries.
- Invalid filter values can cause SQL errors or expose database structure.
Challenge: Implement a search endpoint with filtering (status, role, date range) and pagination. Show how filter parameters are preserved in next/prev links.
FAQ
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro