[1.6.x] Fixed #16433 -- Fixed a help_text/read only field interaction that caused an admin crash.

Thanks chris at cogdon.org for the report and admackin for the patch.

Backport of af953c45cc from master
This commit is contained in:
Tim Graham 2013-08-29 09:39:31 -04:00
parent 58157be5ad
commit ef1259342b
4 changed files with 25 additions and 5 deletions

View File

@ -320,10 +320,15 @@ def label_for_field(name, model, model_admin=None, return_attr=False):
def help_text_for_field(name, model): def help_text_for_field(name, model):
try:
help_text = model._meta.get_field_by_name(name)[0].help_text
except models.FieldDoesNotExist:
help_text = "" help_text = ""
try:
field_data = model._meta.get_field_by_name(name)
except models.FieldDoesNotExist:
pass
else:
field = field_data[0]
if not isinstance(field, RelatedObject):
help_text = field.help_text
return smart_text(help_text) return smart_text(help_text)

View File

@ -450,6 +450,10 @@ class GadgetAdmin(admin.ModelAdmin):
return CustomChangeList return CustomChangeList
class ToppingAdmin(admin.ModelAdmin):
readonly_fields = ('pizzas',)
class PizzaAdmin(admin.ModelAdmin): class PizzaAdmin(admin.ModelAdmin):
readonly_fields = ('toppings',) readonly_fields = ('toppings',)
@ -755,7 +759,7 @@ site.register(Book, inlines=[ChapterInline])
site.register(Promo) site.register(Promo)
site.register(ChapterXtra1, ChapterXtra1Admin) site.register(ChapterXtra1, ChapterXtra1Admin)
site.register(Pizza, PizzaAdmin) site.register(Pizza, PizzaAdmin)
site.register(Topping) site.register(Topping, ToppingAdmin)
site.register(Album, AlbumAdmin) site.register(Album, AlbumAdmin)
site.register(Question) site.register(Question)
site.register(Answer) site.register(Answer)

View File

@ -495,7 +495,7 @@ class Topping(models.Model):
class Pizza(models.Model): class Pizza(models.Model):
name = models.CharField(max_length=20) name = models.CharField(max_length=20)
toppings = models.ManyToManyField('Topping') toppings = models.ManyToManyField('Topping', related_name='pizzas')
class Album(models.Model): class Album(models.Model):

View File

@ -49,7 +49,7 @@ from .models import (Article, BarAccount, CustomArticle, EmptyModel, FooAccount,
OtherStory, ComplexSortedPerson, PluggableSearchPerson, Parent, Child, AdminOrderedField, OtherStory, ComplexSortedPerson, PluggableSearchPerson, Parent, Child, AdminOrderedField,
AdminOrderedModelMethod, AdminOrderedAdminMethod, AdminOrderedCallable, AdminOrderedModelMethod, AdminOrderedAdminMethod, AdminOrderedCallable,
Report, MainPrepopulated, RelatedPrepopulated, UnorderedObject, Report, MainPrepopulated, RelatedPrepopulated, UnorderedObject,
Simple, UndeletableObject, Choice, ShortMessage, Telegram) Simple, UndeletableObject, Choice, ShortMessage, Telegram, Pizza, Topping)
from .admin import site, site2 from .admin import site, site2
@ -3559,6 +3559,17 @@ class ReadonlyTest(TestCase):
self.assertContains(response, '<p>No opinion</p>', html=True) self.assertContains(response, '<p>No opinion</p>', html=True)
self.assertNotContains(response, '<p>(None)</p>') self.assertNotContains(response, '<p>(None)</p>')
def test_readonly_backwards_ref(self):
"""
Regression test for #16433 - backwards references for related objects
broke if the related field is read-only due to the help_text attribute
"""
topping = Topping.objects.create(name='Salami')
pizza = Pizza.objects.create(name='Americano')
pizza.toppings.add(topping)
response = self.client.get('/test_admin/admin/admin_views/topping/add/')
self.assertEqual(response.status_code, 200)
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',)) @override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
class RawIdFieldsTest(TestCase): class RawIdFieldsTest(TestCase):