Ticket #16311: patch_list_filter_limit_to_related_with_tests.diff
File patch_list_filter_limit_to_related_with_tests.diff, 6.5 KB (added by , 13 years ago) |
---|
-
django/db/models/fields/__init__.py
355 355 def get_validator_unique_lookup_type(self): 356 356 return '%s__exact' % self.name 357 357 358 def get_choices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH ):358 def get_choices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH, limit_choices_to=None): 359 359 """Returns choices with a default blank choices included, for use 360 360 as SelectField choices for this field.""" 361 361 first_choice = include_blank and blank_choice or [] 362 362 if self.choices: 363 363 return first_choice + list(self.choices) 364 364 rel_model = self.rel.to 365 limit_choices_to = limit_choices_to and limit_choices_to or self.rel.limit_choices_to 365 366 if hasattr(self.rel, 'get_related_field'): 366 lst = [(getattr(x, self.rel.get_related_field().attname), smart_unicode(x)) for x in rel_model._default_manager.complex_filter( self.rel.limit_choices_to)]367 lst = [(getattr(x, self.rel.get_related_field().attname), smart_unicode(x)) for x in rel_model._default_manager.complex_filter(limit_choices_to)] 367 368 else: 368 lst = [(x._get_pk_val(), smart_unicode(x)) for x in rel_model._default_manager.complex_filter( self.rel.limit_choices_to)]369 lst = [(x._get_pk_val(), smart_unicode(x)) for x in rel_model._default_manager.complex_filter(limit_choices_to)] 369 370 return first_choice + lst 370 371 371 372 def get_choices_default(self): -
django/contrib/admin/filters.py
160 160 self.lookup_val = request.GET.get(self.lookup_kwarg, None) 161 161 self.lookup_val_isnull = request.GET.get( 162 162 self.lookup_kwarg_isnull, None) 163 self.lookup_choices = field.get_choices(include_blank=False)163 self.lookup_choices = self.field_choices(field, request, model_admin) 164 164 self.title = self.lookup_title 165 165 166 166 def has_output(self): … … 175 175 def used_params(self): 176 176 return [self.lookup_kwarg, self.lookup_kwarg_isnull] 177 177 178 def field_choices(self, field, request, model_admin): 179 return field.get_choices(include_blank=False) 180 178 181 def choices(self, cl): 179 182 from django.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE 180 183 yield { … … 399 402 } 400 403 401 404 FieldListFilter.register(lambda f: True, AllValuesFieldListFilter) 405 406 407 class RelatedOnlyFieldListFilter(RelatedFieldListFilter): 408 def field_choices(self, field, request, model_admin): 409 limit_choices_to = {'pk__in': set(model_admin.queryset(request).values_list(field.name, flat=True))} 410 return field.get_choices(include_blank=False, limit_choices_to=limit_choices_to) -
tests/regressiontests/admin_filters/tests.py
10 10 from django.contrib.auth.models import User 11 11 from django.contrib.admin.views.main import ChangeList 12 12 from django.contrib.admin import site, ModelAdmin, SimpleListFilter 13 from django.contrib.admin.filters import RelatedOnlyFieldListFilter 13 14 14 15 from models import Book 15 16 … … 69 70 list_filter = ('year', 'author', 'contributors', 'is_best_seller', 'date_registered', 'no') 70 71 ordering = ('-id',) 71 72 73 class BookAdminRelatedOnlyFilter(ModelAdmin): 74 list_filter = ('year', ('author', RelatedOnlyFieldListFilter), ('contributors', RelatedOnlyFieldListFilter),\ 75 'is_best_seller', 'date_registered', 'no') 76 ordering = ('-id',) 77 72 78 class DecadeFilterBookAdmin(ModelAdmin): 73 79 list_filter = ('author', DecadeListFilterWithTitleAndParameter) 74 80 ordering = ('-id',) … … 223 229 def test_relatedfieldlistfilter_foreignkey(self): 224 230 modeladmin = BookAdmin(Book, site) 225 231 232 request = self.request_factory.get('/') 233 changelist = self.get_changelist(request, Book, modeladmin) 234 235 # Make sure that all users are present in the author's list filter 236 filterspec = changelist.get_filters(request)[0][1] 237 self.assertEqual(filterspec.lookup_choices, [(1, u'alfred'), (2, u'bob'), (3, u'lisa')]) 238 226 239 request = self.request_factory.get('/', {'author__isnull': 'True'}) 227 240 changelist = self.get_changelist(request, Book, modeladmin) 228 241 … … 251 264 def test_relatedfieldlistfilter_manytomany(self): 252 265 modeladmin = BookAdmin(Book, site) 253 266 267 request = self.request_factory.get('/') 268 changelist = self.get_changelist(request, Book, modeladmin) 269 270 # Make sure that all users are present in the contrib's list filter 271 filterspec = changelist.get_filters(request)[0][2] 272 self.assertEqual(filterspec.lookup_choices, [(1, u'alfred'), (2, u'bob'), (3, u'lisa')]) 273 254 274 request = self.request_factory.get('/', {'contributors__isnull': 'True'}) 255 275 changelist = self.get_changelist(request, Book, modeladmin) 256 276 … … 328 348 self.assertEqual(choice['selected'], True) 329 349 self.assertEqual(choice['query_string'], '?books_contributed__id__exact=%d' % self.django_book.pk) 330 350 351 def test_relatedonlyfieldlistfilter_foreignkey(self): 352 modeladmin = BookAdminRelatedOnlyFilter(Book, site) 353 354 request = self.request_factory.get('/') 355 changelist = self.get_changelist(request, Book, modeladmin) 356 357 # Make sure that only actual authors are present in author's list filter 358 filterspec = changelist.get_filters(request)[0][1] 359 self.assertEqual(filterspec.lookup_choices, [(1, u'alfred'), (2, u'bob')]) 360 361 def test_relatedonlyfieldlistfilter_manytomany(self): 362 modeladmin = BookAdminRelatedOnlyFilter(Book, site) 363 364 request = self.request_factory.get('/') 365 changelist = self.get_changelist(request, Book, modeladmin) 366 367 # Make sure that only actual contributors are present in contrib's list filter 368 filterspec = changelist.get_filters(request)[0][2] 369 self.assertEqual(filterspec.lookup_choices, [(2, u'bob'), (3, u'lisa')]) 370 331 371 def test_booleanfieldlistfilter(self): 332 372 modeladmin = BookAdmin(Book, site) 333 373 self.verify_booleanfieldlistfilter(modeladmin)