Skip to content

Commit

Permalink
Merge pull request #357 from tswicegood/fix-list-attr
Browse files Browse the repository at this point in the history
Removed admin's swallowing of AttributeError (#16655, #18593, #18747)
  • Loading branch information
aaugustin committed Sep 8, 2012
2 parents d823bb7 + ccd1bb0 commit 617d077
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 4 deletions.
2 changes: 1 addition & 1 deletion django/contrib/admin/templatetags/admin_list.py
Expand Up @@ -182,7 +182,7 @@ def items_for_result(cl, result, form):
row_class = '' row_class = ''
try: try:
f, attr, value = lookup_field(field_name, result, cl.model_admin) f, attr, value = lookup_field(field_name, result, cl.model_admin)
except (AttributeError, ObjectDoesNotExist): except ObjectDoesNotExist:
result_repr = EMPTY_CHANGELIST_VALUE result_repr = EMPTY_CHANGELIST_VALUE
else: else:
if f is None: if f is None:
Expand Down
16 changes: 14 additions & 2 deletions tests/regressiontests/admin_views/admin.py
Expand Up @@ -27,11 +27,14 @@
Album, Question, Answer, ComplexSortedPerson, PrePopulatedPostLargeSlug, Album, Question, Answer, ComplexSortedPerson, PrePopulatedPostLargeSlug,
AdminOrderedField, AdminOrderedModelMethod, AdminOrderedAdminMethod, AdminOrderedField, AdminOrderedModelMethod, AdminOrderedAdminMethod,
AdminOrderedCallable, Report, Color2, UnorderedObject, MainPrepopulated, AdminOrderedCallable, Report, Color2, UnorderedObject, MainPrepopulated,
RelatedPrepopulated, UndeletableObject) RelatedPrepopulated, UndeletableObject, Simple)




def callable_year(dt_value): def callable_year(dt_value):
return dt_value.year try:
return dt_value.year
except AttributeError:
return None
callable_year.admin_order_field = 'date' callable_year.admin_order_field = 'date'




Expand Down Expand Up @@ -575,6 +578,14 @@ def change_view(self, *args, **kwargs):
return super(UndeletableObjectAdmin, self).change_view(*args, **kwargs) return super(UndeletableObjectAdmin, self).change_view(*args, **kwargs)




def callable_on_unknown(obj):
return obj.unknown


class AttributeErrorRaisingAdmin(admin.ModelAdmin):
list_display = [callable_on_unknown, ]


site = admin.AdminSite(name="admin") site = admin.AdminSite(name="admin")
site.register(Article, ArticleAdmin) site.register(Article, ArticleAdmin)
site.register(CustomArticle, CustomArticleAdmin) site.register(CustomArticle, CustomArticleAdmin)
Expand Down Expand Up @@ -648,6 +659,7 @@ def change_view(self, *args, **kwargs):
site.register(AdminOrderedAdminMethod, AdminOrderedAdminMethodAdmin) site.register(AdminOrderedAdminMethod, AdminOrderedAdminMethodAdmin)
site.register(AdminOrderedCallable, AdminOrderedCallableAdmin) site.register(AdminOrderedCallable, AdminOrderedCallableAdmin)
site.register(Color2, CustomTemplateFilterColorAdmin) site.register(Color2, CustomTemplateFilterColorAdmin)
site.register(Simple, AttributeErrorRaisingAdmin)


# Register core models we need in our tests # Register core models we need in our tests
from django.contrib.auth.models import User, Group from django.contrib.auth.models import User, Group
Expand Down
1 change: 1 addition & 0 deletions tests/regressiontests/admin_views/customadmin.py
Expand Up @@ -49,3 +49,4 @@ def queryset(self, request):
site.register(models.ChapterXtra1, base_admin.ChapterXtra1Admin) site.register(models.ChapterXtra1, base_admin.ChapterXtra1Admin)
site.register(User, UserLimitedAdmin) site.register(User, UserLimitedAdmin)
site.register(models.UndeletableObject, base_admin.UndeletableObjectAdmin) site.register(models.UndeletableObject, base_admin.UndeletableObjectAdmin)
site.register(models.Simple, base_admin.AttributeErrorRaisingAdmin)
6 changes: 6 additions & 0 deletions tests/regressiontests/admin_views/models.py
Expand Up @@ -649,3 +649,9 @@ class UndeletableObject(models.Model):
Refs #10057. Refs #10057.
""" """
name = models.CharField(max_length=255) name = models.CharField(max_length=255)


class Simple(models.Model):
"""
Simple model with nothing on it for use in testing
"""
16 changes: 15 additions & 1 deletion tests/regressiontests/admin_views/tests.py
Expand Up @@ -46,7 +46,7 @@
OtherStory, ComplexSortedPerson, Parent, Child, AdminOrderedField, OtherStory, ComplexSortedPerson, Parent, Child, AdminOrderedField,
AdminOrderedModelMethod, AdminOrderedAdminMethod, AdminOrderedCallable, AdminOrderedModelMethod, AdminOrderedAdminMethod, AdminOrderedCallable,
Report, MainPrepopulated, RelatedPrepopulated, UnorderedObject, Report, MainPrepopulated, RelatedPrepopulated, UnorderedObject,
UndeletableObject) Simple, UndeletableObject)




ERROR_MESSAGE = "Please enter the correct username and password \ ERROR_MESSAGE = "Please enter the correct username and password \
Expand Down Expand Up @@ -578,6 +578,20 @@ def test_change_view_with_show_delete_extra_context(self):
(self.urlbit, instance.pk)) (self.urlbit, instance.pk))
self.assertNotContains(response, 'deletelink') self.assertNotContains(response, 'deletelink')


def test_allows_attributeerror_to_bubble_up(self):
"""
Ensure that AttributeErrors are allowed to bubble when raised inside
a change list view.
Requires a model to be created so there's something to be displayed
Refs: #16655, #18593, and #18747
"""
Simple.objects.create()
with self.assertRaises(AttributeError):
self.client.get('/test_admin/%s/admin_views/simple/' % self.urlbit)


@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',)) @override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
class AdminViewFormUrlTest(TestCase): class AdminViewFormUrlTest(TestCase):
urls = "regressiontests.admin_views.urls" urls = "regressiontests.admin_views.urls"
Expand Down

0 comments on commit 617d077

Please sign in to comment.