Ticket #17972: 17972.listfilter-fk-with-tofield.1-3-X.diff
File 17972.listfilter-fk-with-tofield.1-3-X.diff, 7.1 KB (added by , 13 years ago) |
---|
-
django/contrib/admin/filterspecs.py
diff -r a6d8d77ea99e django/contrib/admin/filterspecs.py
a b 74 74 self.lookup_title = other_model._meta.verbose_name 75 75 else: 76 76 self.lookup_title = f.verbose_name # use field name 77 rel_name = other_model._meta.pk.name 77 if hasattr(f, 'rel'): 78 rel_name = f.rel.get_related_field().name 79 else: 80 rel_name = other_model._meta.pk.name 78 81 self.lookup_kwarg = '%s__%s__exact' % (self.field_path, rel_name) 79 self.lookup_kwarg_isnull = '%s__isnull' % (self.field_path)82 self.lookup_kwarg_isnull = '%s__isnull' % self.field_path 80 83 self.lookup_val = request.GET.get(self.lookup_kwarg, None) 81 84 self.lookup_val_isnull = request.GET.get( 82 85 self.lookup_kwarg_isnull, None) … … 176 179 177 180 class DateFieldFilterSpec(FilterSpec): 178 181 def __init__(self, f, request, params, model, model_admin, 179 field_path=None): 182 field_path=None): 180 183 super(DateFieldFilterSpec, self).__init__(f, request, params, model, 181 184 model_admin, 182 185 field_path=field_path) -
django/contrib/admin/options.py
diff -r a6d8d77ea99e django/contrib/admin/options.py
a b 225 225 # if foo has been specificially included in the lookup list; so 226 226 # drop __id if it is the last part. However, first we need to find 227 227 # the pk attribute name. 228 pk_attr_name = None228 rel_name = None 229 229 for part in parts[:-1]: 230 230 field, _, _, _ = model._meta.get_field_by_name(part) 231 231 if hasattr(field, 'rel'): 232 232 model = field.rel.to 233 pk_attr_name = model._meta.pk.name233 rel_name = field.rel.get_related_field().name 234 234 elif isinstance(field, RelatedObject): 235 235 model = field.model 236 pk_attr_name = model._meta.pk.name236 rel_name = model._meta.pk.name 237 237 else: 238 pk_attr_name = None239 if pk_attr_name and len(parts) > 1 and parts[-1] == pk_attr_name:238 rel_name = None 239 if rel_name and len(parts) > 1 and parts[-1] == rel_name: 240 240 parts.pop() 241 241 242 242 try: -
tests/regressiontests/admin_filterspecs/models.py
diff -r a6d8d77ea99e tests/regressiontests/admin_filterspecs/models.py
a b 21 21 default=NO, 22 22 choices=YES_NO_CHOICES 23 23 ) 24 25 26 class Department(models.Model): 27 code = models.CharField(max_length=4, unique=True) 28 description = models.CharField(max_length=50, blank=True, null=True) 29 30 def __unicode__(self): 31 return self.description 32 33 class Employee(models.Model): 34 department = models.ForeignKey(Department, to_field="code") 35 name = models.CharField(max_length=100) 36 37 def __unicode__(self): 38 return self.name 39 40 class Meta: 41 ordering = ['id'] 42 No newline at end of file -
tests/regressiontests/admin_filterspecs/tests.py
diff -r a6d8d77ea99e tests/regressiontests/admin_filterspecs/tests.py
a b 6 6 from django.contrib.admin.views.main import ChangeList 7 7 from django.utils.encoding import force_unicode 8 8 9 from models import Book, BoolTest 9 from models import Book, BoolTest, Employee, Department 10 10 11 11 def select_by(dictlist, key, value): 12 12 return [x for x in dictlist if x[key] == value][0] … … 200 200 self.assertEqual(choice['selected'], True) 201 201 self.assertEqual(choice['query_string'], '?completed__exact=1') 202 202 203 def test_fk_with_to_field(self): 204 """ 205 Ensure that a filter on a FK respects the FK's to_field attribute. 206 Refs #17972. 207 """ 208 modeladmin = EmployeeAdmin(Employee, admin.site) 209 210 dev = Department.objects.create(code='DEV', description='Development') 211 design = Department.objects.create(code='DSN', description='Design') 212 john = Employee.objects.create(name='John Blue', department=dev) 213 jack = Employee.objects.create(name='Jack Red', department=design) 214 215 request = self.request_factory.get('/', {}) 216 changelist = self.get_changelist(request, Employee, modeladmin) 217 218 # Make sure the correct queryset is returned 219 queryset = changelist.get_query_set() 220 self.assertEqual(list(queryset), [john, jack]) 221 222 filterspec = changelist.get_filters(request)[0][-1] 223 self.assertEqual(force_unicode(filterspec.title()), u'department') 224 choices = list(filterspec.choices(changelist)) 225 226 self.assertEqual(choices[0]['display'], u'All') 227 self.assertEqual(choices[0]['selected'], True) 228 self.assertEqual(choices[0]['query_string'], '?') 229 230 self.assertEqual(choices[1]['display'], u'Development') 231 self.assertEqual(choices[1]['selected'], False) 232 self.assertEqual(choices[1]['query_string'], '?department__code__exact=DEV') 233 234 self.assertEqual(choices[2]['display'], u'Design') 235 self.assertEqual(choices[2]['selected'], False) 236 self.assertEqual(choices[2]['query_string'], '?department__code__exact=DSN') 237 238 # Filter by Department=='Development' -------------------------------- 239 240 request = self.request_factory.get('/', {'department__code__exact': 'DEV'}) 241 changelist = self.get_changelist(request, Employee, modeladmin) 242 243 # Make sure the correct queryset is returned 244 queryset = changelist.get_query_set() 245 self.assertEqual(list(queryset), [john]) 246 247 filterspec = changelist.get_filters(request)[0][-1] 248 self.assertEqual(force_unicode(filterspec.title()), u'department') 249 choices = list(filterspec.choices(changelist)) 250 251 self.assertEqual(choices[0]['display'], u'All') 252 self.assertEqual(choices[0]['selected'], False) 253 self.assertEqual(choices[0]['query_string'], '?') 254 255 self.assertEqual(choices[1]['display'], u'Development') 256 self.assertEqual(choices[1]['selected'], True) 257 self.assertEqual(choices[1]['query_string'], '?department__code__exact=DEV') 258 259 self.assertEqual(choices[2]['display'], u'Design') 260 self.assertEqual(choices[2]['selected'], False) 261 self.assertEqual(choices[2]['query_string'], '?department__code__exact=DSN') 262 263 203 264 class CustomUserAdmin(UserAdmin): 204 265 list_filter = ('books_authored', 'books_contributed') 205 266 … … 209 270 210 271 class BoolTestAdmin(admin.ModelAdmin): 211 272 list_filter = ('completed',) 273 274 class EmployeeAdmin(admin.ModelAdmin): 275 list_display = ['name', 'department'] 276 list_filter = ['department'] 277 No newline at end of file