Ticket #17972: 17972.listfilter-fk-with-tofield.diff
File 17972.listfilter-fk-with-tofield.diff, 7.2 KB (added by , 13 years ago) |
---|
-
django/contrib/admin/filters.py
diff --git a/django/contrib/admin/filters.py b/django/contrib/admin/filters.py index b64445e..76b8d30 100644
a b class FieldListFilter(ListFilter): 155 155 class RelatedFieldListFilter(FieldListFilter): 156 156 def __init__(self, field, request, params, model, model_admin, field_path): 157 157 other_model = get_model_from_relation(field) 158 rel_name = other_model._meta.pk.name 158 if hasattr(field, 'rel'): 159 rel_name = field.rel.get_related_field().name 160 else: 161 rel_name = other_model._meta.pk.name 159 162 self.lookup_kwarg = '%s__%s__exact' % (field_path, rel_name) 160 163 self.lookup_kwarg_isnull = '%s__isnull' % field_path 161 164 self.lookup_val = request.GET.get(self.lookup_kwarg, None) -
django/contrib/admin/options.py
diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py index 73c2958..2071792 100644
a b class BaseModelAdmin(object): 245 245 # if foo has been specificially included in the lookup list; so 246 246 # drop __id if it is the last part. However, first we need to find 247 247 # the pk attribute name. 248 pk_attr_name = None248 rel_name = None 249 249 for part in parts[:-1]: 250 250 try: 251 251 field, _, _, _ = model._meta.get_field_by_name(part) … … class BaseModelAdmin(object): 255 255 return True 256 256 if hasattr(field, 'rel'): 257 257 model = field.rel.to 258 pk_attr_name = model._meta.pk.name258 rel_name = field.rel.get_related_field().name 259 259 elif isinstance(field, RelatedObject): 260 260 model = field.model 261 pk_attr_name = model._meta.pk.name261 rel_name = model._meta.pk.name 262 262 else: 263 pk_attr_name = None264 if pk_attr_name and len(parts) > 1 and parts[-1] == pk_attr_name:263 rel_name = None 264 if rel_name and len(parts) > 1 and parts[-1] == rel_name: 265 265 parts.pop() 266 266 267 267 if len(parts) == 1: -
tests/regressiontests/admin_filters/models.py
diff --git a/tests/regressiontests/admin_filters/models.py b/tests/regressiontests/admin_filters/models.py index 2fa6e66..deb8ee8 100644
a b class Book(models.Model): 13 13 14 14 def __unicode__(self): 15 15 return self.title 16 17 18 class Department(models.Model): 19 code = models.CharField(max_length=4, unique=True) 20 description = models.CharField(max_length=50, blank=True, null=True) 21 22 def __unicode__(self): 23 return self.description 24 25 class Employee(models.Model): 26 department = models.ForeignKey(Department, to_field="code") 27 name = models.CharField(max_length=100) 28 29 def __unicode__(self): 30 return self.name 31 No newline at end of file -
tests/regressiontests/admin_filters/tests.py
diff --git a/tests/regressiontests/admin_filters/tests.py b/tests/regressiontests/admin_filters/tests.py index b42dfd7..d87c447 100644
a b import datetime 4 4 5 5 from django.contrib.admin import (site, ModelAdmin, SimpleListFilter, 6 6 BooleanFieldListFilter) 7 from django.contrib.admin.options import IncorrectLookupParameters8 7 from django.contrib.admin.views.main import ChangeList 9 8 from django.contrib.auth.admin import UserAdmin 10 9 from django.contrib.auth.models import User … … from django.test import TestCase, RequestFactory 13 12 from django.test.utils import override_settings 14 13 from django.utils.encoding import force_unicode 15 14 16 from .models import Book 15 from .models import Book, Department, Employee 17 16 18 17 19 18 def select_by(dictlist, key, value): … … class DecadeFilterBookAdminParameterEndsWith__In(ModelAdmin): 113 112 class DecadeFilterBookAdminParameterEndsWith__Isnull(ModelAdmin): 114 113 list_filter = (DecadeListFilterParameterEndsWith__Isnull,) 115 114 115 class EmployeeAdmin(ModelAdmin): 116 list_display = ['name', 'department'] 117 list_filter = ['department'] 116 118 117 119 118 120 class ListFiltersTests(TestCase): … … class ListFiltersTests(TestCase): 633 635 choices = list(filterspec.choices(changelist)) 634 636 self.assertEqual(choices[2]['display'], u'the 1990\'s') 635 637 self.assertEqual(choices[2]['selected'], True) 636 self.assertEqual(choices[2]['query_string'], '?decade__isnull=the+90s') 637 No newline at end of file 638 self.assertEqual(choices[2]['query_string'], '?decade__isnull=the+90s') 639 640 def test_fk_with_to_field(self): 641 """ 642 Ensure that a filter on a FK respects the FK's to_field attribute. 643 Refs #17972. 644 """ 645 modeladmin = EmployeeAdmin(Employee, site) 646 647 dev = Department.objects.create(code='DEV', description='Development') 648 design = Department.objects.create(code='DSN', description='Design') 649 john = Employee.objects.create(name='John Blue', department=dev) 650 jack = Employee.objects.create(name='Jack Red', department=design) 651 652 request = self.request_factory.get('/', {}) 653 changelist = self.get_changelist(request, Employee, modeladmin) 654 655 # Make sure the correct queryset is returned 656 queryset = changelist.get_query_set(request) 657 self.assertEqual(list(queryset), [john, jack]) 658 659 filterspec = changelist.get_filters(request)[0][-1] 660 self.assertEqual(force_unicode(filterspec.title), u'department') 661 choices = list(filterspec.choices(changelist)) 662 663 self.assertEqual(choices[0]['display'], u'All') 664 self.assertEqual(choices[0]['selected'], True) 665 self.assertEqual(choices[0]['query_string'], '?') 666 667 self.assertEqual(choices[1]['display'], u'Development') 668 self.assertEqual(choices[1]['selected'], False) 669 self.assertEqual(choices[1]['query_string'], '?department__code__exact=DEV') 670 671 self.assertEqual(choices[2]['display'], u'Design') 672 self.assertEqual(choices[2]['selected'], False) 673 self.assertEqual(choices[2]['query_string'], '?department__code__exact=DSN') 674 675 # Filter by Department=='Development' -------------------------------- 676 677 request = self.request_factory.get('/', {'department__code__exact': 'DEV'}) 678 changelist = self.get_changelist(request, Employee, modeladmin) 679 680 # Make sure the correct queryset is returned 681 queryset = changelist.get_query_set(request) 682 self.assertEqual(list(queryset), [john]) 683 684 filterspec = changelist.get_filters(request)[0][-1] 685 self.assertEqual(force_unicode(filterspec.title), u'department') 686 choices = list(filterspec.choices(changelist)) 687 688 self.assertEqual(choices[0]['display'], u'All') 689 self.assertEqual(choices[0]['selected'], False) 690 self.assertEqual(choices[0]['query_string'], '?') 691 692 self.assertEqual(choices[1]['display'], u'Development') 693 self.assertEqual(choices[1]['selected'], True) 694 self.assertEqual(choices[1]['query_string'], '?department__code__exact=DEV') 695 696 self.assertEqual(choices[2]['display'], u'Design') 697 self.assertEqual(choices[2]['selected'], False) 698 self.assertEqual(choices[2]['query_string'], '?department__code__exact=DSN')