#16311 closed New feature (fixed)
Option to limit list_filter to related_objects of instances of the list
Reported by: | Owned by: | nobody | |
---|---|---|---|
Component: | contrib.admin | Version: | dev |
Severity: | Normal | Keywords: | admin, list_filter, limit_choices_to |
Cc: | Triage Stage: | Accepted | |
Has patch: | yes | Needs documentation: | no |
Needs tests: | no | Patch needs improvement: | no |
Easy pickings: | no | UI/UX: | no |
Description
I know there are many snippets and blog entries to do that but it is a common use case to limit the FK/related model choices to the very objects displayed in the list and maybe the core team would consider to implement it directly in the Django admin.
The +10 lines patch I provide allow you to limit the choices for a FK/M2M to the current object list by adding the attribute RELATED_FIELD_filter_related_only=True
to your ModelAdmin.
By example :
class Order(models.Model): ... support = models.ForeignKey(Support) parutions = models.ManyToManyField(Parution, through='OrderParution', related_name='order') class OrderAdmin(admin.ModelAdmin): ... list_filter = ('support', 'agency', 'parutions') parutions_filter_related_only=True support_filter_related_only=True
Attachments (4)
Change History (18)
by , 13 years ago
Attachment: | patch_list_filter_limit_to_related.diff added |
---|
comment:1 by , 13 years ago
Bad choice using a dict as a default argument. If you add something to this, it will be changed in all calls to the method. Use None instead.
comment:2 by , 13 years ago
Needs documentation: | set |
---|---|
Needs tests: | set |
Patch needs improvement: | set |
Triage Stage: | Unreviewed → Accepted |
Procedurally -- the dict argument is important feedback. The patch also requires tests and documentation.
I'm inclined to say that this shouldn't be a top-level ModelAdmin argument, but a configuration option of the list_filter item itself. The new ListFilter class (in trunk) should provide a better interface to handle this.
comment:3 by , 13 years ago
Yeah, sorry that was a bit terse. Written in bed from iPad, wife complained about tap-tap-tap.
What it should say is:
When you have a literal dict or list as a default argument to a function or method, this generally results in undesired behaviour. If you modify this variable, rather than assign to it, then you change the default value for _every_ call to the function/method.
ie (this is a list, but a dict is the same behaviour):
def foo(bar=[]): return bar baz = foo() baz # =>[] baz.append(None) baz # => [None] foo() # => [None]
You almost always expect that last call to foo() to return [], not [None].
comment:4 by , 13 years ago
I agree with russellm for the API design; the class you specifically want to look at is contrib.admin.filters.RelatedFieldListFilter
. The functionality of that class could be extended to accept configuration options. The developer could then assign a custom filter class to a given field:
class MyModelAdmin(ModelAdmin): list_filter = (('my_field', MyRelatedFieldListFilter),)
comment:5 by , 13 years ago
Thanks for the feedback.
I have rewritten the patch for the trunk according to your suggestions and the usage is now :
from django.contrib.admin.filters import RelatedOnlyFieldListFilter class OrderAdmin(admin.ModelAdmin): ... list_filter = ('support', 'agency', ('parutions', RelatedOnlyFieldListFilter))
Writting some tests now.
By the way, is list_filer
a typo in contrib.admin.views.main
(line 82) ?
for list_filer in self.list_filter: if callable(list_filer): # This is simply a custom list filter class. spec = list_filer(request, cleaned_params, self.model, self.model_admin) else: field_path = None if isinstance(list_filer, (tuple, list)): # This is a custom FieldListFilter class for a given field. field, field_list_filter_class = list_filer else: # This is simply a field name, so use the default # FieldListFilter class that has been registered for # the type of the given field. field, field_list_filter_class = list_filer, FieldListFilter.create
by , 13 years ago
Attachment: | patch_list_filter_limit_to_related2.diff added |
---|
Patch against trunk with a subclass of RelatedFieldListFilter.
by , 13 years ago
Attachment: | patch_list_filter_limit_to_related_with_tests.diff added |
---|
Regresssion tests added.
comment:7 by , 11 years ago
comment:8 by , 11 years ago
Version: | 1.3 → 1.5 |
---|
comment:9 by , 10 years ago
Version: | 1.5 → master |
---|
PR against master : https://github.com/django/django/pull/2695
follow-up: 11 comment:10 by , 10 years ago
Needs tests: | unset |
---|---|
Patch needs improvement: | unset |
The PR lacks documentation.
comment:11 by , 10 years ago
Needs documentation: | unset |
---|
comment:12 by , 10 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
Patch for django 1.3