Loading AUTHORS +1 −0 Original line number Diff line number Diff line Loading @@ -242,6 +242,7 @@ answer newbie questions, and generally made Django that much better: Owen Griffiths Espen Grindhaug <http://grindhaug.org/> Mike Grouchy <http://mikegrouchy.com/> Stanislas Guerra <stan@slashdev.me> Janos Guljas Thomas Güttler <hv@tbz-pariv.de> Horst Gutmann <zerok@zerokspot.com> Loading django/contrib/admin/__init__.py +3 −2 Original line number Diff line number Diff line Loading @@ -6,7 +6,8 @@ from django.contrib.admin.options import (HORIZONTAL, VERTICAL, ModelAdmin, StackedInline, TabularInline) from django.contrib.admin.filters import (ListFilter, SimpleListFilter, FieldListFilter, BooleanFieldListFilter, RelatedFieldListFilter, ChoicesFieldListFilter, DateFieldListFilter, AllValuesFieldListFilter) ChoicesFieldListFilter, DateFieldListFilter, AllValuesFieldListFilter, RelatedOnlyFieldListFilter) from django.contrib.admin.sites import AdminSite, site from django.utils.module_loading import autodiscover_modules Loading @@ -15,7 +16,7 @@ __all__ = [ "StackedInline", "TabularInline", "AdminSite", "site", "ListFilter", "SimpleListFilter", "FieldListFilter", "BooleanFieldListFilter", "RelatedFieldListFilter", "ChoicesFieldListFilter", "DateFieldListFilter", "AllValuesFieldListFilter", "autodiscover", "AllValuesFieldListFilter", "RelatedOnlyFieldListFilter", "autodiscover", ] Loading django/contrib/admin/filters.py +10 −1 Original line number Diff line number Diff line Loading @@ -170,7 +170,7 @@ class RelatedFieldListFilter(FieldListFilter): self.lookup_kwarg_isnull = '%s__isnull' % field_path self.lookup_val = request.GET.get(self.lookup_kwarg) self.lookup_val_isnull = request.GET.get(self.lookup_kwarg_isnull) self.lookup_choices = field.get_choices(include_blank=False) self.lookup_choices = self.field_choices(field, request, model_admin) super(RelatedFieldListFilter, self).__init__( field, request, params, model, model_admin, field_path) if hasattr(field, 'verbose_name'): Loading @@ -191,6 +191,9 @@ class RelatedFieldListFilter(FieldListFilter): def expected_parameters(self): return [self.lookup_kwarg, self.lookup_kwarg_isnull] def field_choices(self, field, request, model_admin): return field.get_choices(include_blank=False) def choices(self, cl): from django.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE yield { Loading Loading @@ -410,3 +413,9 @@ class AllValuesFieldListFilter(FieldListFilter): } FieldListFilter.register(lambda f: True, AllValuesFieldListFilter) class RelatedOnlyFieldListFilter(RelatedFieldListFilter): def field_choices(self, field, request, model_admin): limit_choices_to = {'pk__in': set(model_admin.get_queryset(request).values_list(field.name, flat=True))} return field.get_choices(include_blank=False, limit_choices_to=limit_choices_to) django/db/models/fields/__init__.py +4 −3 Original line number Diff line number Diff line Loading @@ -726,7 +726,7 @@ class Field(RegisterLookupMixin): def get_validator_unique_lookup_type(self): return '%s__exact' % self.name def get_choices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH): def get_choices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH, limit_choices_to=None): """Returns choices with a default blank choices included, for use as SelectField choices for this field.""" blank_defined = False Loading @@ -743,15 +743,16 @@ class Field(RegisterLookupMixin): if self.choices: return first_choice + choices rel_model = self.rel.to limit_choices_to = limit_choices_to or self.get_limit_choices_to() if hasattr(self.rel, 'get_related_field'): lst = [(getattr(x, self.rel.get_related_field().attname), smart_text(x)) for x in rel_model._default_manager.complex_filter( self.get_limit_choices_to())] limit_choices_to)] else: lst = [(x._get_pk_val(), smart_text(x)) for x in rel_model._default_manager.complex_filter( self.get_limit_choices_to())] limit_choices_to)] return first_choice + lst def get_choices_default(self): Loading docs/ref/contrib/admin/index.txt +14 −0 Original line number Diff line number Diff line Loading @@ -880,6 +880,20 @@ subclass:: ('is_staff', admin.BooleanFieldListFilter), ) .. versionadded:: 1.8 You can now limit the choices of a related model to the objects involved in that relation using ``RelatedOnlyFieldListFilter``:: class BookAdmin(admin.ModelAdmin): list_filter = ( ('author', admin.RelatedOnlyFieldListFilter), ) Assuming ``author`` is a ``ForeignKey`` to a ``User`` model, this will limit the ``list_filter`` choices to the users who have written a book instead of listing all users. .. note:: The ``FieldListFilter`` API is considered internal and might be Loading Loading
AUTHORS +1 −0 Original line number Diff line number Diff line Loading @@ -242,6 +242,7 @@ answer newbie questions, and generally made Django that much better: Owen Griffiths Espen Grindhaug <http://grindhaug.org/> Mike Grouchy <http://mikegrouchy.com/> Stanislas Guerra <stan@slashdev.me> Janos Guljas Thomas Güttler <hv@tbz-pariv.de> Horst Gutmann <zerok@zerokspot.com> Loading
django/contrib/admin/__init__.py +3 −2 Original line number Diff line number Diff line Loading @@ -6,7 +6,8 @@ from django.contrib.admin.options import (HORIZONTAL, VERTICAL, ModelAdmin, StackedInline, TabularInline) from django.contrib.admin.filters import (ListFilter, SimpleListFilter, FieldListFilter, BooleanFieldListFilter, RelatedFieldListFilter, ChoicesFieldListFilter, DateFieldListFilter, AllValuesFieldListFilter) ChoicesFieldListFilter, DateFieldListFilter, AllValuesFieldListFilter, RelatedOnlyFieldListFilter) from django.contrib.admin.sites import AdminSite, site from django.utils.module_loading import autodiscover_modules Loading @@ -15,7 +16,7 @@ __all__ = [ "StackedInline", "TabularInline", "AdminSite", "site", "ListFilter", "SimpleListFilter", "FieldListFilter", "BooleanFieldListFilter", "RelatedFieldListFilter", "ChoicesFieldListFilter", "DateFieldListFilter", "AllValuesFieldListFilter", "autodiscover", "AllValuesFieldListFilter", "RelatedOnlyFieldListFilter", "autodiscover", ] Loading
django/contrib/admin/filters.py +10 −1 Original line number Diff line number Diff line Loading @@ -170,7 +170,7 @@ class RelatedFieldListFilter(FieldListFilter): self.lookup_kwarg_isnull = '%s__isnull' % field_path self.lookup_val = request.GET.get(self.lookup_kwarg) self.lookup_val_isnull = request.GET.get(self.lookup_kwarg_isnull) self.lookup_choices = field.get_choices(include_blank=False) self.lookup_choices = self.field_choices(field, request, model_admin) super(RelatedFieldListFilter, self).__init__( field, request, params, model, model_admin, field_path) if hasattr(field, 'verbose_name'): Loading @@ -191,6 +191,9 @@ class RelatedFieldListFilter(FieldListFilter): def expected_parameters(self): return [self.lookup_kwarg, self.lookup_kwarg_isnull] def field_choices(self, field, request, model_admin): return field.get_choices(include_blank=False) def choices(self, cl): from django.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE yield { Loading Loading @@ -410,3 +413,9 @@ class AllValuesFieldListFilter(FieldListFilter): } FieldListFilter.register(lambda f: True, AllValuesFieldListFilter) class RelatedOnlyFieldListFilter(RelatedFieldListFilter): def field_choices(self, field, request, model_admin): limit_choices_to = {'pk__in': set(model_admin.get_queryset(request).values_list(field.name, flat=True))} return field.get_choices(include_blank=False, limit_choices_to=limit_choices_to)
django/db/models/fields/__init__.py +4 −3 Original line number Diff line number Diff line Loading @@ -726,7 +726,7 @@ class Field(RegisterLookupMixin): def get_validator_unique_lookup_type(self): return '%s__exact' % self.name def get_choices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH): def get_choices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH, limit_choices_to=None): """Returns choices with a default blank choices included, for use as SelectField choices for this field.""" blank_defined = False Loading @@ -743,15 +743,16 @@ class Field(RegisterLookupMixin): if self.choices: return first_choice + choices rel_model = self.rel.to limit_choices_to = limit_choices_to or self.get_limit_choices_to() if hasattr(self.rel, 'get_related_field'): lst = [(getattr(x, self.rel.get_related_field().attname), smart_text(x)) for x in rel_model._default_manager.complex_filter( self.get_limit_choices_to())] limit_choices_to)] else: lst = [(x._get_pk_val(), smart_text(x)) for x in rel_model._default_manager.complex_filter( self.get_limit_choices_to())] limit_choices_to)] return first_choice + lst def get_choices_default(self): Loading
docs/ref/contrib/admin/index.txt +14 −0 Original line number Diff line number Diff line Loading @@ -880,6 +880,20 @@ subclass:: ('is_staff', admin.BooleanFieldListFilter), ) .. versionadded:: 1.8 You can now limit the choices of a related model to the objects involved in that relation using ``RelatedOnlyFieldListFilter``:: class BookAdmin(admin.ModelAdmin): list_filter = ( ('author', admin.RelatedOnlyFieldListFilter), ) Assuming ``author`` is a ``ForeignKey`` to a ``User`` model, this will limit the ``list_filter`` choices to the users who have written a book instead of listing all users. .. note:: The ``FieldListFilter`` API is considered internal and might be Loading