Ticket #16311: patch16311-1.4.1.diff

File patch16311-1.4.1.diff, 7.0 KB (added by Stanislas <stanislas.guerra@…>, 12 years ago)

Patch against Django-1.4.1.

  • django/contrib/admin/filters.py

    diff --git a/django/contrib/admin/filters.py b/django/contrib/admin/filters.py
    index 76b8d30..f33cde4 100644
    a b class RelatedFieldListFilter(FieldListFilter):  
    164164        self.lookup_val = request.GET.get(self.lookup_kwarg, None)
    165165        self.lookup_val_isnull = request.GET.get(
    166166                                      self.lookup_kwarg_isnull, None)
    167         self.lookup_choices = field.get_choices(include_blank=False)
     167        self.lookup_choices = self.field_choices(field, request, model_admin)
    168168        super(RelatedFieldListFilter, self).__init__(
    169169            field, request, params, model, model_admin, field_path)
    170170        if hasattr(field, 'verbose_name'):
    class RelatedFieldListFilter(FieldListFilter):  
    185185    def expected_parameters(self):
    186186        return [self.lookup_kwarg, self.lookup_kwarg_isnull]
    187187
     188    def field_choices(self, field, request, model_admin):
     189        return field.get_choices(include_blank=False)
     190
    188191    def choices(self, cl):
    189192        from django.contrib.admin.views.main import EMPTY_CHANGELIST_VALUE
    190193        yield {
    class AllValuesFieldListFilter(FieldListFilter):  
    403406            }
    404407
    405408FieldListFilter.register(lambda f: True, AllValuesFieldListFilter)
     409
     410
     411class RelatedOnlyFieldListFilter(RelatedFieldListFilter):
     412    def field_choices(self, field, request, model_admin):
     413        limit_choices_to = {'pk__in': set(model_admin.queryset(request).values_list(field.name, flat=True))}
     414        return field.get_choices(include_blank=False, limit_choices_to=limit_choices_to)
  • django/db/models/fields/__init__.py

    diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py
    index 22546c2..db2c5bf 100644
    a b class Field(object):  
    386386    def get_validator_unique_lookup_type(self):
    387387        return '%s__exact' % self.name
    388388
    389     def get_choices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH):
     389    def get_choices(self, include_blank=True, blank_choice=BLANK_CHOICE_DASH, limit_choices_to=None):
    390390        """Returns choices with a default blank choices included, for use
    391391        as SelectField choices for this field."""
    392392        first_choice = include_blank and blank_choice or []
    393393        if self.choices:
    394394            return first_choice + list(self.choices)
    395395        rel_model = self.rel.to
     396        limit_choices_to = limit_choices_to and limit_choices_to or self.rel.limit_choices_to
    396397        if hasattr(self.rel, 'get_related_field'):
    397398            lst = [(getattr(x, self.rel.get_related_field().attname),
    398399                        smart_unicode(x))
    399400                   for x in rel_model._default_manager.complex_filter(
    400                        self.rel.limit_choices_to)]
     401                       limit_choices_to)]
    401402        else:
    402             lst = [(x._get_pk_val(), smart_unicode(x))
     403            lst = [(x._get_pk_val(), smart_unicode(x)) 
    403404                   for x in rel_model._default_manager.complex_filter(
    404                        self.rel.limit_choices_to)]
     405                       limit_choices_to)]
    405406        return first_choice + lst
    406407
    407408    def get_choices_default(self):
  • tests/regressiontests/admin_filters/tests.py

    diff --git a/tests/regressiontests/admin_filters/tests.py b/tests/regressiontests/admin_filters/tests.py
    index e2a12c9..178e3cd 100644
    a b from django.contrib.admin import (site, ModelAdmin, SimpleListFilter,  
    77from django.contrib.admin.views.main import ChangeList
    88from django.contrib.auth.admin import UserAdmin
    99from django.contrib.auth.models import User
     10from django.contrib.admin.filters import RelatedOnlyFieldListFilter
    1011from django.core.exceptions import ImproperlyConfigured
    1112from django.test import TestCase, RequestFactory
    1213from django.test.utils import override_settings
    class BookAdmin(ModelAdmin):  
    8788class BookAdminWithTupleBooleanFilter(BookAdmin):
    8889    list_filter = ('year', 'author', 'contributors', ('is_best_seller', BooleanFieldListFilter), 'date_registered', 'no')
    8990
     91class BookAdminRelatedOnlyFilter(ModelAdmin):
     92    list_filter = ('year', ('author', RelatedOnlyFieldListFilter), ('contributors', RelatedOnlyFieldListFilter),\
     93                   'is_best_seller', 'date_registered', 'no')
     94    ordering = ('-id',)
     95
    9096class DecadeFilterBookAdmin(ModelAdmin):
    9197    list_filter = ('author', DecadeListFilterWithTitleAndParameter)
    9298    ordering = ('-id',)
    class ListFiltersTests(TestCase):  
    261267    def test_relatedfieldlistfilter_foreignkey(self):
    262268        modeladmin = BookAdmin(Book, site)
    263269
     270        request = self.request_factory.get('/')
     271        changelist = self.get_changelist(request, Book, modeladmin)
     272
     273        # Make sure that all users are present in the author's list filter
     274        filterspec = changelist.get_filters(request)[0][1]
     275        self.assertEqual(filterspec.lookup_choices, [(1, u'alfred'), (2, u'bob'), (3, u'lisa')])
     276
    264277        request = self.request_factory.get('/', {'author__isnull': 'True'})
    265278        changelist = self.get_changelist(request, Book, modeladmin)
    266279
    class ListFiltersTests(TestCase):  
    289302    def test_relatedfieldlistfilter_manytomany(self):
    290303        modeladmin = BookAdmin(Book, site)
    291304
     305        request = self.request_factory.get('/')
     306        changelist = self.get_changelist(request, Book, modeladmin)
     307
     308        # Make sure that all users are present in the contrib's list filter
     309        filterspec = changelist.get_filters(request)[0][2]
     310        self.assertEqual(filterspec.lookup_choices, [(1, u'alfred'), (2, u'bob'), (3, u'lisa')])
     311
    292312        request = self.request_factory.get('/', {'contributors__isnull': 'True'})
    293313        changelist = self.get_changelist(request, Book, modeladmin)
    294314
    class ListFiltersTests(TestCase):  
    366386        self.assertEqual(choice['selected'], True)
    367387        self.assertEqual(choice['query_string'], '?books_contributed__id__exact=%d' % self.django_book.pk)
    368388
     389    def test_relatedonlyfieldlistfilter_foreignkey(self):
     390        modeladmin = BookAdminRelatedOnlyFilter(Book, site)
     391
     392        request = self.request_factory.get('/')
     393        changelist = self.get_changelist(request, Book, modeladmin)
     394
     395        # Make sure that only actual authors are present in author's list filter
     396        filterspec = changelist.get_filters(request)[0][1]
     397        self.assertEqual(filterspec.lookup_choices, [(1, u'alfred'), (2, u'bob')])
     398
     399    def test_relatedonlyfieldlistfilter_manytomany(self):
     400        modeladmin = BookAdminRelatedOnlyFilter(Book, site)
     401
     402        request = self.request_factory.get('/')
     403        changelist = self.get_changelist(request, Book, modeladmin)
     404
     405        # Make sure that only actual contributors are present in contrib's list filter
     406        filterspec = changelist.get_filters(request)[0][2]
     407        self.assertEqual(filterspec.lookup_choices, [(2, u'bob'), (3, u'lisa')])
     408
    369409    def test_booleanfieldlistfilter(self):
    370410        modeladmin = BookAdmin(Book, site)
    371411        self.verify_booleanfieldlistfilter(modeladmin)
Back to Top