[1.7.x] Fixed #22087 -- Made AdminReadonlyField respect ModelForm Meta overrides.

Backport of 16afffffe8 from master
This commit is contained in:
Ben Davis 2014-02-18 16:44:33 -06:00 committed by Tim Graham
parent b4f165fe94
commit 2460484486
4 changed files with 50 additions and 4 deletions

View File

@ -136,7 +136,6 @@ class AdminField(object):
class AdminReadonlyField(object): class AdminReadonlyField(object):
def __init__(self, form, field, is_first, model_admin=None): def __init__(self, form, field, is_first, model_admin=None):
label = label_for_field(field, form._meta.model, model_admin)
# Make self.field look a little bit like a field. This means that # Make self.field look a little bit like a field. This means that
# {{ field.name }} must be a useful class name to identify the field. # {{ field.name }} must be a useful class name to identify the field.
# For convenience, store other field-related data here too. # For convenience, store other field-related data here too.
@ -144,11 +143,22 @@ class AdminReadonlyField(object):
class_name = field.__name__ if field.__name__ != '<lambda>' else '' class_name = field.__name__ if field.__name__ != '<lambda>' else ''
else: else:
class_name = field class_name = field
if form._meta.labels and class_name in form._meta.labels:
label = form._meta.labels[class_name]
else:
label = label_for_field(field, form._meta.model, model_admin)
if form._meta.help_texts and class_name in form._meta.help_texts:
help_text = form._meta.help_texts[class_name]
else:
help_text = help_text_for_field(class_name, form._meta.model)
self.field = { self.field = {
'name': class_name, 'name': class_name,
'label': label, 'label': label,
'help_text': help_text,
'field': field, 'field': field,
'help_text': help_text_for_field(class_name, form._meta.model)
} }
self.form = form self.form = form
self.model_admin = model_admin self.model_admin = model_admin

View File

@ -35,7 +35,7 @@ from .models import (Article, Chapter, Child, Parent, Picture, Widget,
UnchangeableObject, UserMessenger, Simple, Choice, ShortMessage, Telegram, UnchangeableObject, UserMessenger, Simple, Choice, ShortMessage, Telegram,
FilteredManager, EmptyModelHidden, EmptyModelVisible, EmptyModelMixin, FilteredManager, EmptyModelHidden, EmptyModelVisible, EmptyModelMixin,
State, City, Restaurant, Worker, ParentWithDependentChildren, State, City, Restaurant, Worker, ParentWithDependentChildren,
DependentChild, StumpJoke) DependentChild, StumpJoke, FieldOverridePost)
def callable_year(dt_value): def callable_year(dt_value):
@ -435,6 +435,22 @@ class PostAdmin(admin.ModelAdmin):
value.short_description = 'Value in $US' value.short_description = 'Value in $US'
class FieldOverridePostForm(forms.ModelForm):
model = FieldOverridePost
class Meta:
help_texts = {
'posted': 'Overridden help text for the date',
}
labels = {
'public': 'Overridden public label',
}
class FieldOverridePostAdmin(PostAdmin):
form = FieldOverridePostForm
class CustomChangeList(ChangeList): class CustomChangeList(ChangeList):
def get_queryset(self, request): def get_queryset(self, request):
return self.root_queryset.filter(pk=9999) # Does not exist return self.root_queryset.filter(pk=9999) # Does not exist
@ -833,6 +849,7 @@ site.register(Recommender)
site.register(Collector, CollectorAdmin) site.register(Collector, CollectorAdmin)
site.register(Category, CategoryAdmin) site.register(Category, CategoryAdmin)
site.register(Post, PostAdmin) site.register(Post, PostAdmin)
site.register(FieldOverridePost, FieldOverridePostAdmin)
site.register(Gadget, GadgetAdmin) site.register(Gadget, GadgetAdmin)
site.register(Villain) site.register(Villain)
site.register(SuperVillain) site.register(SuperVillain)

View File

@ -438,6 +438,13 @@ class Post(models.Model):
return "Very awesome." return "Very awesome."
# Proxy model to test overridden fields attrs on Post model so as not to
# interfere with other tests.
class FieldOverridePost(Post):
class Meta:
proxy = True
@python_2_unicode_compatible @python_2_unicode_compatible
class Gadget(models.Model): class Gadget(models.Model):
name = models.CharField(max_length=100) name = models.CharField(max_length=100)

View File

@ -52,7 +52,7 @@ from .models import (Article, BarAccount, CustomArticle, EmptyModel, FooAccount,
Report, MainPrepopulated, RelatedPrepopulated, UnorderedObject, Report, MainPrepopulated, RelatedPrepopulated, UnorderedObject,
Simple, UndeletableObject, UnchangeableObject, Choice, ShortMessage, Simple, UndeletableObject, UnchangeableObject, Choice, ShortMessage,
Telegram, Pizza, Topping, FilteredManager, City, Restaurant, Worker, Telegram, Pizza, Topping, FilteredManager, City, Restaurant, Worker,
ParentWithDependentChildren, Character) ParentWithDependentChildren, Character, FieldOverridePost)
from .admin import site, site2, CityAdmin from .admin import site, site2, CityAdmin
@ -3693,6 +3693,18 @@ class ReadonlyTest(TestCase):
response = self.client.get('/test_admin/admin/admin_views/topping/add/') response = self.client.get('/test_admin/admin/admin_views/topping/add/')
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
def test_readonly_field_overrides(self):
"""
Regression test for #22087 - ModelForm Meta overrides are ignored by
AdminReadonlyField
"""
p = FieldOverridePost.objects.create(title="Test Post", content="Test Content")
response = self.client.get('/test_admin/admin/admin_views/fieldoverridepost/%d/' % p.pk)
self.assertEqual(response.status_code, 200)
self.assertContains(response, '<p class="help">Overridden help text for the date</p>')
self.assertContains(response, '<label for="id_public">Overridden public label:</label>', html=True)
self.assertNotContains(response, "Some help text for the date (with unicode ŠĐĆŽćžšđ)")
@override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',)) @override_settings(PASSWORD_HASHERS=('django.contrib.auth.hashers.SHA1PasswordHasher',))
class LimitChoicesToInAdminTest(TestCase): class LimitChoicesToInAdminTest(TestCase):