Fixed #16080 -- Handle admin list filter items with two characters better. Thanks, Ales Zoulek and Julien Phalip.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@16274 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
c0303f5d81
commit
4a4b6b271e
|
@ -73,18 +73,16 @@ def validate(cls, model):
|
||||||
" associated with a field name."
|
" associated with a field name."
|
||||||
% (cls.__name__, idx, item.__name__))
|
% (cls.__name__, idx, item.__name__))
|
||||||
else:
|
else:
|
||||||
try:
|
if isinstance(item, (tuple, list)):
|
||||||
# Check for option #2 (tuple)
|
|
||||||
field, list_filter_class = item
|
|
||||||
except (TypeError, ValueError):
|
|
||||||
# item is option #1
|
|
||||||
field = item
|
|
||||||
else:
|
|
||||||
# item is option #2
|
# item is option #2
|
||||||
|
field, list_filter_class = item
|
||||||
if not issubclass(list_filter_class, FieldListFilter):
|
if not issubclass(list_filter_class, FieldListFilter):
|
||||||
raise ImproperlyConfigured("'%s.list_filter[%d][1]'"
|
raise ImproperlyConfigured("'%s.list_filter[%d][1]'"
|
||||||
" is '%s' which is not of type FieldListFilter."
|
" is '%s' which is not of type FieldListFilter."
|
||||||
% (cls.__name__, idx, list_filter_class.__name__))
|
% (cls.__name__, idx, list_filter_class.__name__))
|
||||||
|
else:
|
||||||
|
# item is option #1
|
||||||
|
field = item
|
||||||
# Validate the field string
|
# Validate the field string
|
||||||
try:
|
try:
|
||||||
get_fields_from_path(model, field)
|
get_fields_from_path(model, field)
|
||||||
|
|
|
@ -97,10 +97,10 @@ class ChangeList(object):
|
||||||
self.model, self.model_admin)
|
self.model, self.model_admin)
|
||||||
else:
|
else:
|
||||||
field_path = None
|
field_path = None
|
||||||
try:
|
if isinstance(list_filer, (tuple, list)):
|
||||||
# This is custom FieldListFilter class for a given field.
|
# This is a custom FieldListFilter class for a given field.
|
||||||
field, field_list_filter_class = list_filer
|
field, field_list_filter_class = list_filer
|
||||||
except (TypeError, ValueError):
|
else:
|
||||||
# This is simply a field name, so use the default
|
# This is simply a field name, so use the default
|
||||||
# FieldListFilter class that has been registered for
|
# FieldListFilter class that has been registered for
|
||||||
# the type of the given field.
|
# the type of the given field.
|
||||||
|
|
|
@ -8,6 +8,7 @@ class Book(models.Model):
|
||||||
contributors = models.ManyToManyField(User, related_name='books_contributed', blank=True, null=True)
|
contributors = models.ManyToManyField(User, related_name='books_contributed', blank=True, null=True)
|
||||||
is_best_seller = models.NullBooleanField(default=0)
|
is_best_seller = models.NullBooleanField(default=0)
|
||||||
date_registered = models.DateField(null=True)
|
date_registered = models.DateField(null=True)
|
||||||
|
no = models.IntegerField(verbose_name=u'number', blank=True, null=True) # This field is intentionally 2 characters long. See #16080.
|
||||||
|
|
||||||
def __unicode__(self):
|
def __unicode__(self):
|
||||||
return self.title
|
return self.title
|
||||||
|
|
|
@ -66,7 +66,7 @@ class CustomUserAdmin(UserAdmin):
|
||||||
list_filter = ('books_authored', 'books_contributed')
|
list_filter = ('books_authored', 'books_contributed')
|
||||||
|
|
||||||
class BookAdmin(ModelAdmin):
|
class BookAdmin(ModelAdmin):
|
||||||
list_filter = ('year', 'author', 'contributors', 'is_best_seller', 'date_registered')
|
list_filter = ('year', 'author', 'contributors', 'is_best_seller', 'date_registered', 'no')
|
||||||
order_by = '-id'
|
order_by = '-id'
|
||||||
|
|
||||||
class DecadeFilterBookAdmin(ModelAdmin):
|
class DecadeFilterBookAdmin(ModelAdmin):
|
||||||
|
@ -100,8 +100,8 @@ class ListFiltersTests(TestCase):
|
||||||
|
|
||||||
# Books
|
# Books
|
||||||
self.djangonaut_book = Book.objects.create(title='Djangonaut: an art of living', year=2009, author=self.alfred, is_best_seller=True, date_registered=self.today)
|
self.djangonaut_book = Book.objects.create(title='Djangonaut: an art of living', year=2009, author=self.alfred, is_best_seller=True, date_registered=self.today)
|
||||||
self.bio_book = Book.objects.create(title='Django: a biography', year=1999, author=self.alfred, is_best_seller=False)
|
self.bio_book = Book.objects.create(title='Django: a biography', year=1999, author=self.alfred, is_best_seller=False, no=207)
|
||||||
self.django_book = Book.objects.create(title='The Django Book', year=None, author=self.bob, is_best_seller=None, date_registered=self.today)
|
self.django_book = Book.objects.create(title='The Django Book', year=None, author=self.bob, is_best_seller=None, date_registered=self.today, no=103)
|
||||||
self.gipsy_book = Book.objects.create(title='Gipsy guitar for dummies', year=2002, is_best_seller=True, date_registered=self.one_week_ago)
|
self.gipsy_book = Book.objects.create(title='Gipsy guitar for dummies', year=2002, is_best_seller=True, date_registered=self.one_week_ago)
|
||||||
self.gipsy_book.contributors = [self.bob, self.lisa]
|
self.gipsy_book.contributors = [self.bob, self.lisa]
|
||||||
self.gipsy_book.save()
|
self.gipsy_book.save()
|
||||||
|
@ -528,3 +528,22 @@ class ListFiltersTests(TestCase):
|
||||||
self.assertEqual(choices[2]['display'], u'the 2000\'s')
|
self.assertEqual(choices[2]['display'], u'the 2000\'s')
|
||||||
self.assertEqual(choices[2]['selected'], False)
|
self.assertEqual(choices[2]['selected'], False)
|
||||||
self.assertEqual(choices[2]['query_string'], '?publication-decade=the+00s')
|
self.assertEqual(choices[2]['query_string'], '?publication-decade=the+00s')
|
||||||
|
|
||||||
|
def test_two_characters_long_field(self):
|
||||||
|
"""
|
||||||
|
Ensure that list_filter works with two-characters long field names.
|
||||||
|
Refs #16080.
|
||||||
|
"""
|
||||||
|
modeladmin = BookAdmin(Book, site)
|
||||||
|
request = self.request_factory.get('/', {'no': '207'})
|
||||||
|
changelist = self.get_changelist(request, Book, modeladmin)
|
||||||
|
|
||||||
|
# Make sure the correct queryset is returned
|
||||||
|
queryset = changelist.get_query_set(request)
|
||||||
|
self.assertEqual(list(queryset), [self.bio_book])
|
||||||
|
|
||||||
|
filterspec = changelist.get_filters(request)[0][-1]
|
||||||
|
self.assertEqual(force_unicode(filterspec.title), u'number')
|
||||||
|
choices = list(filterspec.choices(changelist))
|
||||||
|
self.assertEqual(choices[2]['selected'], True)
|
||||||
|
self.assertEqual(choices[2]['query_string'], '?no=207')
|
||||||
|
|
|
@ -34,6 +34,7 @@ class ValidationTestModel(models.Model):
|
||||||
is_active = models.BooleanField()
|
is_active = models.BooleanField()
|
||||||
pub_date = models.DateTimeField()
|
pub_date = models.DateTimeField()
|
||||||
band = models.ForeignKey(Band)
|
band = models.ForeignKey(Band)
|
||||||
|
no = models.IntegerField(verbose_name="Number", blank=True, null=True) # This field is intentionally 2 characters long. See #16080.
|
||||||
|
|
||||||
def decade_published_in(self):
|
def decade_published_in(self):
|
||||||
return self.pub_date.strftime('%Y')[:3] + "0's"
|
return self.pub_date.strftime('%Y')[:3] + "0's"
|
||||||
|
|
|
@ -911,7 +911,7 @@ class ValidationTests(unittest.TestCase):
|
||||||
# Valid declarations below -----------
|
# Valid declarations below -----------
|
||||||
|
|
||||||
class ValidationTestModelAdmin(ModelAdmin):
|
class ValidationTestModelAdmin(ModelAdmin):
|
||||||
list_filter = ('is_active', AwesomeFilter, ('is_active', BooleanFieldListFilter))
|
list_filter = ('is_active', AwesomeFilter, ('is_active', BooleanFieldListFilter), 'no')
|
||||||
|
|
||||||
validate(ValidationTestModelAdmin, ValidationTestModel)
|
validate(ValidationTestModelAdmin, ValidationTestModel)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue