mirror of
https://github.com/django/django.git
synced 2025-03-31 19:46:42 +00:00
Fixed #17308 -- Enabled the use of short_description on properties in the admin.
This commit is contained in:
parent
b1ac241ddc
commit
cec9558fba
@ -269,8 +269,9 @@ def lookup_field(name, obj, model_admin=None):
|
|||||||
|
|
||||||
def label_for_field(name, model, model_admin=None, return_attr=False):
|
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
|
Returns a sensible label for a field name. The name can be a callable,
|
||||||
name of an object attributes, as well as a genuine fields. If return_attr is
|
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.
|
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.
|
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"):
|
if hasattr(attr, "short_description"):
|
||||||
label = 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):
|
elif callable(attr):
|
||||||
if attr.__name__ == "<lambda>":
|
if attr.__name__ == "<lambda>":
|
||||||
label = "--"
|
label = "--"
|
||||||
@ -315,6 +320,7 @@ def label_for_field(name, model, model_admin=None, return_attr=False):
|
|||||||
else:
|
else:
|
||||||
return label
|
return label
|
||||||
|
|
||||||
|
|
||||||
def help_text_for_field(name, model):
|
def help_text_for_field(name, model):
|
||||||
try:
|
try:
|
||||||
help_text = model._meta.get_field_by_name(name)[0].help_text
|
help_text = model._meta.get_field_by_name(name)[0].help_text
|
||||||
|
@ -464,7 +464,7 @@ subclass::
|
|||||||
list_display = ('upper_case_name',)
|
list_display = ('upper_case_name',)
|
||||||
|
|
||||||
def upper_case_name(self, obj):
|
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'
|
upper_case_name.short_description = 'Name'
|
||||||
|
|
||||||
* A string representing an attribute on the model. This behaves almost
|
* 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
|
The above will tell Django to order by the ``first_name`` field when
|
||||||
trying to sort by ``colored_first_name`` in the admin.
|
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
|
* .. versionadded:: 1.6
|
||||||
|
|
||||||
The field names in ``list_display`` will also appear as CSS classes in
|
The field names in ``list_display`` will also appear as CSS classes in
|
||||||
|
@ -236,6 +236,20 @@ class UtilTests(unittest.TestCase):
|
|||||||
("not Really the Model", MockModelAdmin.test_from_model)
|
("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):
|
def test_related_name(self):
|
||||||
"""
|
"""
|
||||||
Regression test for #13963
|
Regression test for #13963
|
||||||
|
Loading…
x
Reference in New Issue
Block a user