Skip to content

feat: Django-style filtering system (#52) - #54

Merged
borhanst merged 1 commit into
mainfrom
feat/django-style-filters
Aug 20, 2026
Merged

feat: Django-style filtering system (#52)#54
borhanst merged 1 commit into
mainfrom
feat/django-style-filters

Conversation

@borhanst

Copy link
Copy Markdown
Owner

Closes #52

Summary

Implements a robust, ORM-agnostic filtering system for the admin API and admin UI list views, following Django's django-filter conventions.

Lookup types added

  • ?filter_name=value — exact match (existing)
  • ?filter_name__icontains=term — case-insensitive contains
  • ?filter_name__startswith=Jo / __endswith=hn
  • ?filter_price__gt=100 / __gte / __lt / __lte
  • ?filter_price__range=10,200 — inclusive range
  • ?filter_id__in=1,2,3 — in list
  • legacy __from / __to range params still supported

Filter classes

  • TextFilter — exact + icontains/startswith/endswith
  • ChoiceFilter — new, for relation/FK fields, rendered as a select (auto-detected in FilterRegistry.auto_generate())
  • IntegerFilter / NumericFilter — gt/gte/lt/lte/range/in
  • DateRangeFilter / DatetimeRangeFilter / TimeFilter — comparison + range + in
  • BooleanFilter / EnumFilter — with choices
  • RelationFilter kept as a backwards-compatible alias of ChoiceFilter

ORM-agnostic

  • Filters build clauses through the QueryBackend protocol; QueryBackend gains an and_ combinator (added to SQLAlchemy + memory backends).
  • In-memory backend now interprets %-anchored ilike patterns (startswith/endswith/contains).
  • Type detection normalized to lowercase so both SQLAlchemy class names and schema-backend type names are recognized.

Admin UI

  • Text fields render a __icontains text input.
  • Numeric/integer fields render Min (__gte) / Max (__lte) inputs.
  • Shared lookup parsing (filters/lookups.py) is used by both the HTML list views and the JSON API.

Tests

33 new tests: lookup parsing, per-filter clause building, registry auto-detection (SQLAlchemy + memory), JSON API end-to-end for every lookup, admin UI list-view filtering, and in-memory backend lookups. Full suite: 879 passed.

Docs

Updated docs/guide/filters.md, docs/guide/features.md, and CHANGELOG.md.

Implements a robust filtering system (#52) for the admin API and UI
following django-filter conventions:

- New lookups: icontains, startswith, endswith, gt, gte, lt, lte,
  range and in, on top of exact matches and legacy from/to.
- New ChoiceFilter auto-registered for FK/ManyToMany columns; numeric
  filters gain full comparison lookups.
- Shared lookup parsing in filters/lookups.py used by both the HTML
  list views and the JSON API.
- ORM-agnostic: QueryBackend gains and_; in-memory backend now handles
  %-anchored ilike patterns.
- Admin UI renders icontains input for text fields and min/max inputs
  for numeric fields.
- Docs, changelog, and 33 new tests (unit + API + in-memory + UI).
@borhanst
borhanst merged commit ca63476 into main Aug 20, 2026
3 checks passed
@borhanst
borhanst deleted the feat/django-style-filters branch August 20, 2026 07:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Implement robust filtering system like Django filters

1 participant