Fixed #17308 -- Enabled the use of short_description on properties in the admin.

This commit is contained in:
Wiktor Kolodziej 2013-05-21 13:03:45 +02:00 committed by Florian Apolloner
parent b1ac241ddc
commit cec9558fba
3 changed files with 44 additions and 3 deletions

View File

@ -269,8 +269,9 @@ def lookup_field(name, obj, model_admin=None):
def label_for_field(name, model, model_admin=None, return_attr=False):
"""
Returns a sensible label for a field name. The name can be a callable or the
name of an object attributes, as well as a genuine fields. If return_attr is
Returns a sensible label for a field name. The name can be a callable,
property (but not created with @property decorator) or the name of an
object's attribute, as well as a genuine fields. If return_attr is
True, the resolved attribute (which could be a callable) is also returned.
This will be None if (and only if) the name refers to a field.
"""
@ -303,6 +304,10 @@ def label_for_field(name, model, model_admin=None, return_attr=False):
if hasattr(attr, "short_description"):
label = attr.short_description
elif (isinstance(attr, property) and
hasattr(attr, "fget") and
hasattr(attr.fget, "short_description")):
label = attr.fget.short_description
elif callable(attr):
if attr.__name__ == "<lambda>":
label = "--"
@ -315,6 +320,7 @@ def label_for_field(name, model, model_admin=None, return_attr=False):
else:
return label
def help_text_for_field(name, model):
try:
help_text = model._meta.get_field_by_name(name)[0].help_text

View File

@ -464,7 +464,7 @@ subclass::
list_display = ('upper_case_name',)
def upper_case_name(self, obj):
return ("%s %s" % (obj.first_name, obj.last_name)).upper()
return ("%s %s" % (obj.first_name, obj.last_name)).upper()
upper_case_name.short_description = 'Name'
* A string representing an attribute on the model. This behaves almost
@ -589,6 +589,27 @@ subclass::
The above will tell Django to order by the ``first_name`` field when
trying to sort by ``colored_first_name`` in the admin.
* Elements of ``list_display`` can also be properties. Please note however,
that due to the way properties work in Python, setting
``short_description`` on a property is only possible when using the
``property()`` function and **not** with the ``@property`` decorator.
For example::
class Person(object):
first_name = models.CharField(max_length=50)
last_name = models.CharField(max_length=50)
def my_property(self):
return self.first_name + ' ' + self.last_name
my_property.short_description = "Full name of the person"
full_name = property(my_property)
class PersonAdmin(admin.ModelAdmin):
list_display = ('full_name',)
* .. versionadded:: 1.6
The field names in ``list_display`` will also appear as CSS classes in

View File

@ -236,6 +236,20 @@ class UtilTests(unittest.TestCase):
("not Really the Model", MockModelAdmin.test_from_model)
)
def test_label_for_property(self):
# NOTE: cannot use @property decorator, because of
# AttributeError: 'property' object has no attribute 'short_description'
class MockModelAdmin(object):
def my_property(self):
return "this if from property"
my_property.short_description = 'property short description'
test_from_property = property(my_property)
self.assertEqual(
label_for_field("test_from_property", Article, model_admin=MockModelAdmin),
'property short description'
)
def test_related_name(self):
"""
Regression test for #13963