Changes between Initial Version and Version 1 of Ticket #36982
- Timestamp:
- Mar 12, 2026, 10:03:47 AM (3 hours ago)
Legend:
- Unmodified
- Added
- Removed
- Modified
-
Ticket #36982 – Description
initial v1 1 The [ ModelAdmin List Filters documentation](https://docs.djangoproject.com/en/6.0/ref/contrib/admin/filters/)states that `list_filter` accepts three types of elements:1 The [https://docs.djangoproject.com/en/6.0/ref/contrib/admin/filters/ ModelAdmin List Filters documentation] states that `list_filter` accepts three types of elements: 2 2 3 3 1. A field name … … 5 5 3. A 2-tuple containing a field name and a subclass of `django.contrib.admin.FieldListFilter` 6 6 7 However, the actual implementation in `ChangeList.get_filters()` ([ source](https://github.com/django/django/blob/3180ddb3f532ef246d318d64225886b7c0593676/django/contrib/admin/views/main.py#L188-L190)) accepts **any callable** — including bare `ListFilter` subclasses — and instantiates them with `(request, lookup_params, self.model, self.model_admin)`:7 However, the actual implementation in `ChangeList.get_filters()` ([https://github.com/django/django/blob/3180ddb3f532ef246d318d64225886b7c0593676/django/contrib/admin/views/main.py#L188-L190 source]) accepts **any callable** — including bare `ListFilter` subclasses — and instantiates them with `(request, lookup_params, self.model, self.model_admin)`: 8 8 9 ```python 9 {{{ 10 #!python 10 11 if callable(list_filter): 11 12 # This is simply a custom list filter class. 12 13 spec = list_filter(request, lookup_params, self.model, self.model_admin) 13 ``` 14 }}} 14 15 15 16 The entire admin filter rendering pipeline (`ChangeList.get_filters()`, `ChangeList.get_queryset()`, and the `admin_list_filter` template tag) only uses methods defined on `ListFilter` itself: `has_output()`, `expected_parameters()`, `queryset()`, `choices()`, `title`, and `template`. Nothing requires `SimpleListFilter` specifically. … … 17 18 This means a direct `ListFilter` subclass (not going through `SimpleListFilter`) works perfectly fine: 18 19 19 ```python 20 {{{ 21 #!python 20 22 class MyFilter(admin.ListFilter): 21 23 title = "My Filter" … … 42 44 class MyAdmin(admin.ModelAdmin): 43 45 list_filter = [MyFilter] 44 ``` 46 }}} 45 47 46 48 This is useful when you need full control over the filter (custom template, multi-value parameters, etc.) without the constraints of `SimpleListFilter`'s `lookups()`/`value()` API or `FieldListFilter`'s field introspection. 47 49 48 The docs should generalise point 2 to say "A subclass of `django.contrib.admin.ListFilter`" instead of "A subclass of `django.contrib.admin.SimpleListFilter`" 50 The docs should generalise point 2 to say "A subclass of `django.contrib.admin.ListFilter`" instead of "A subclass of `django.contrib.admin.SimpleListFilter`".