summaryrefslogtreecommitdiff
path: root/django
diff options
context:
space:
mode:
authorRamiro Morales <cramm0@gmail.com>2011-02-26 01:44:41 +0000
committerRamiro Morales <cramm0@gmail.com>2011-02-26 01:44:41 +0000
commit0a9b5d7adee86def16972debf6441deb96135ce2 (patch)
tree5acf9e37753e2f675b66c1467b75176739393f23 /django
parent4d70d48ecbfe2b972c55c3b4fa1237dfe54f5b6b (diff)
Fixed #15424 -- Corrected lookup of callables listed in admin inlines' `readonly_fields` by passing the right ModelAdmin (sub)class instance when instantiating inline forms admin wrappers. Also, added early validation of its elements. Thanks kmike for the report and Karen for the patch fixing the issue.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@15650 bcc190cf-cafb-0310-a4f2-bffc1f526a37
Diffstat (limited to 'django')
-rw-r--r--django/contrib/admin/helpers.py8
-rw-r--r--django/contrib/admin/util.py2
-rw-r--r--django/contrib/admin/validation.py26
3 files changed, 21 insertions, 15 deletions
diff --git a/django/contrib/admin/helpers.py b/django/contrib/admin/helpers.py
index 3c1bef3f9e..a0eda384f0 100644
--- a/django/contrib/admin/helpers.py
+++ b/django/contrib/admin/helpers.py
@@ -206,14 +206,14 @@ class InlineAdminFormSet(object):
for form, original in zip(self.formset.initial_forms, self.formset.get_queryset()):
yield InlineAdminForm(self.formset, form, self.fieldsets,
self.opts.prepopulated_fields, original, self.readonly_fields,
- model_admin=self.model_admin)
+ model_admin=self.opts)
for form in self.formset.extra_forms:
yield InlineAdminForm(self.formset, form, self.fieldsets,
self.opts.prepopulated_fields, None, self.readonly_fields,
- model_admin=self.model_admin)
+ model_admin=self.opts)
yield InlineAdminForm(self.formset, self.formset.empty_form,
self.fieldsets, self.opts.prepopulated_fields, None,
- self.readonly_fields, model_admin=self.model_admin)
+ self.readonly_fields, model_admin=self.opts)
def fields(self):
fk = getattr(self.formset, "fk", None)
@@ -222,7 +222,7 @@ class InlineAdminFormSet(object):
continue
if field in self.readonly_fields:
yield {
- 'label': label_for_field(field, self.opts.model, self.model_admin),
+ 'label': label_for_field(field, self.opts.model, self.opts),
'widget': {
'is_hidden': False
},
diff --git a/django/contrib/admin/util.py b/django/contrib/admin/util.py
index d3f17d67d4..d0a5293210 100644
--- a/django/contrib/admin/util.py
+++ b/django/contrib/admin/util.py
@@ -249,7 +249,7 @@ def label_for_field(name, model, model_admin=None, return_attr=False):
else:
message = "Unable to lookup '%s' on %s" % (name, model._meta.object_name)
if model_admin:
- message += " or %s" % (model_admin.__name__,)
+ message += " or %s" % (model_admin.__class__.__name__,)
raise AttributeError(message)
if hasattr(attr, "short_description"):
diff --git a/django/contrib/admin/validation.py b/django/contrib/admin/validation.py
index ba3525624d..e0db936df4 100644
--- a/django/contrib/admin/validation.py
+++ b/django/contrib/admin/validation.py
@@ -129,16 +129,7 @@ def validate(cls, model):
get_field(cls, model, opts, 'ordering[%d]' % idx, field)
if hasattr(cls, "readonly_fields"):
- check_isseq(cls, "readonly_fields", cls.readonly_fields)
- for idx, field in enumerate(cls.readonly_fields):
- if not callable(field):
- if not hasattr(cls, field):
- if not hasattr(model, field):
- try:
- opts.get_field(field)
- except models.FieldDoesNotExist:
- raise ImproperlyConfigured("%s.readonly_fields[%d], %r is not a callable or an attribute of %r or found in the model %r."
- % (cls.__name__, idx, field, cls.__name__, model._meta.object_name))
+ check_readonly_fields(cls, model, opts)
# list_select_related = False
# save_as = False
@@ -199,6 +190,9 @@ def validate_inline(cls, parent, parent_model):
"'%s' - this is the foreign key to the parent model "
"%s." % (cls.__name__, fk.name, parent_model.__name__))
+ if hasattr(cls, "readonly_fields"):
+ check_readonly_fields(cls, cls.model, cls.model._meta)
+
def validate_base(cls, model):
opts = model._meta
@@ -384,3 +378,15 @@ def fetch_attr(cls, model, opts, label, field):
except AttributeError:
raise ImproperlyConfigured("'%s.%s' refers to '%s' that is neither a field, method or property of model '%s'."
% (cls.__name__, label, field, model.__name__))
+
+def check_readonly_fields(cls, model, opts):
+ check_isseq(cls, "readonly_fields", cls.readonly_fields)
+ for idx, field in enumerate(cls.readonly_fields):
+ if not callable(field):
+ if not hasattr(cls, field):
+ if not hasattr(model, field):
+ try:
+ opts.get_field(field)
+ except models.FieldDoesNotExist:
+ raise ImproperlyConfigured("%s.readonly_fields[%d], %r is not a callable or an attribute of %r or found in the model %r."
+ % (cls.__name__, idx, field, cls.__name__, model._meta.object_name))