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.
This commit is contained in:
Tim Graham 2013-08-29 09:39:31 -04:00
parent cf8d6e9108
commit af953c45cc
4 changed files with 26 additions and 5 deletions

View File

@ -327,10 +327,15 @@ def label_for_field(name, model, model_admin=None, return_attr=False):
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 = ""
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)

View File

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

View File

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

View File

@ -50,7 +50,8 @@ from .models import (Article, BarAccount, CustomArticle, EmptyModel, FooAccount,
OtherStory, ComplexSortedPerson, PluggableSearchPerson, Parent, Child, AdminOrderedField,
AdminOrderedModelMethod, AdminOrderedAdminMethod, AdminOrderedCallable,
Report, MainPrepopulated, RelatedPrepopulated, UnorderedObject,
Simple, UndeletableObject, UnchangeableObject, Choice, ShortMessage, Telegram)
Simple, UndeletableObject, UnchangeableObject, Choice, ShortMessage,
Telegram, Pizza, Topping)
from .admin import site, site2
@ -3638,6 +3639,17 @@ class ReadonlyTest(TestCase):
self.assertContains(response, '<p>No opinion</p>', html=True)
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',))
class RawIdFieldsTest(TestCase):