Last active
December 13, 2016 14:00
-
-
Save vdboor/451a813b9e3ea622a399cd67d607f69d to your computer and use it in GitHub Desktop.
In the admin sidebar, only show related objects that are in use by the objects shown in the list
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from django.contrib import admin | |
from django.contrib.admin.utils import get_model_from_relation | |
from django.utils.encoding import smart_text | |
class LimitedRelatedFieldListFilter(admin.RelatedFieldListFilter): | |
""" | |
Limit the filter choices in the admin sidebar to objects | |
which are actually used by the objects shown in the list. | |
Usage:: | |
list_filter = ( | |
('fieldname', LimitedRelatedFieldListFilter), | |
) | |
""" | |
def __init__(self, field, request, params, model, model_admin, field_path): | |
# NOTE: | |
# Replaced the entire __init__ code, | |
# to offer a get_queryset() hook that allows limiting the queryset. | |
other_model = get_model_from_relation(field) | |
if hasattr(field, 'rel'): | |
rel_name = field.rel.get_related_field().name | |
else: | |
rel_name = other_model._meta.pk.name | |
self.lookup_kwarg = '%s__%s__exact' % (field_path, rel_name) | |
self.lookup_kwarg_isnull = '%s__isnull' % field_path | |
self.lookup_val = request.GET.get(self.lookup_kwarg, None) | |
self.lookup_val_isnull = request.GET.get( | |
self.lookup_kwarg_isnull, None) | |
self.lookup_choices = [ | |
(x._get_pk_val(), smart_text(x)) for x in self.get_queryset(field) | |
] | |
admin.FieldListFilter.__init__( | |
self, field, request, params, model, model_admin, field_path) | |
if hasattr(field, 'verbose_name'): | |
self.lookup_title = field.verbose_name | |
else: | |
self.lookup_title = other_model._meta.verbose_name | |
self.title = self.lookup_title | |
self.empty_value_display = model_admin.get_empty_value_display() | |
def get_queryset(self, field): | |
# Allow filtering the queryset! | |
other_model = get_model_from_relation(field) | |
return other_model._default_manager.complex_filter(field.rel.limit_choices_to) | |
class SortedLimitedRelatedFieldListFilter(LimitedRelatedFieldListFilter): | |
""" | |
Override the standard RelatedField list filter, to sort the values. | |
Usage:: | |
list_filter = ( | |
('fieldname', SortedLimitedRelatedFieldListFilter), | |
) | |
""" | |
def __init__(self, *args, **kwargs): | |
super(SortedLimitedRelatedFieldListFilter, self).__init__(*args, **kwargs) | |
self.lookup_choices = sorted(self.lookup_choices, key=lambda a: a[1].lower()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment