Loading django/contrib/admin/util.py +7 −2 Original line number Diff line number Diff line Loading @@ -327,10 +327,15 @@ def label_for_field(name, model, model_admin=None, return_attr=False): def help_text_for_field(name, model): help_text = "" try: help_text = model._meta.get_field_by_name(name)[0].help_text field_data = model._meta.get_field_by_name(name) except models.FieldDoesNotExist: help_text = "" pass else: field = field_data[0] if not isinstance(field, RelatedObject): help_text = field.help_text return smart_text(help_text) Loading tests/admin_views/admin.py +5 −1 Original line number Diff line number Diff line Loading @@ -450,6 +450,10 @@ class GadgetAdmin(admin.ModelAdmin): return CustomChangeList class ToppingAdmin(admin.ModelAdmin): readonly_fields = ('pizzas',) class PizzaAdmin(admin.ModelAdmin): readonly_fields = ('toppings',) Loading Loading @@ -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) Loading tests/admin_views/models.py +1 −1 Original line number Diff line number Diff line Loading @@ -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): Loading tests/admin_views/tests.py +13 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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): Loading Loading
django/contrib/admin/util.py +7 −2 Original line number Diff line number Diff line Loading @@ -327,10 +327,15 @@ def label_for_field(name, model, model_admin=None, return_attr=False): def help_text_for_field(name, model): help_text = "" try: help_text = model._meta.get_field_by_name(name)[0].help_text field_data = model._meta.get_field_by_name(name) except models.FieldDoesNotExist: help_text = "" pass else: field = field_data[0] if not isinstance(field, RelatedObject): help_text = field.help_text return smart_text(help_text) Loading
tests/admin_views/admin.py +5 −1 Original line number Diff line number Diff line Loading @@ -450,6 +450,10 @@ class GadgetAdmin(admin.ModelAdmin): return CustomChangeList class ToppingAdmin(admin.ModelAdmin): readonly_fields = ('pizzas',) class PizzaAdmin(admin.ModelAdmin): readonly_fields = ('toppings',) Loading Loading @@ -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) Loading
tests/admin_views/models.py +1 −1 Original line number Diff line number Diff line Loading @@ -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): Loading
tests/admin_views/tests.py +13 −1 Original line number Diff line number Diff line Loading @@ -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 Loading Loading @@ -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): Loading