diff --git a/djadmin2/templatetags/admin2_tags.py b/djadmin2/templatetags/admin2_tags.py index a8a1367..e2eb6e6 100644 --- a/djadmin2/templatetags/admin2_tags.py +++ b/djadmin2/templatetags/admin2_tags.py @@ -97,29 +97,12 @@ def for_object(permissions, obj): return permissions.bind_object(obj) -@register.filter -def get_attr(record, attribute_name): - """ Allows dynamic fetching of model attributes in templates """ - if attribute_name == "__str__": - return record.__unicode__() - attribute = getattr(record, attribute_name) - if callable(attribute): - return attribute() - return attribute - - @register.simple_tag(takes_context=True) def render(context, model_instance, attribute_name): """ This filter applies all renderers specified in admin2.py to the field. """ - # Get the right value for the attribute. Handle special cases like - # callables and the __str__ attribute. - if attribute_name == '__str__': - value = unicode(model_instance) - else: - attribute = getattr(model_instance, attribute_name) - value = attribute() if callable(attribute) else attribute + value = utils.get_attr(model_instance, attribute_name) # Get renderer admin = context['view'].model_admin diff --git a/djadmin2/tests/test_admin2tags.py b/djadmin2/tests/test_admin2tags.py index a2c3cfc..76018c9 100644 --- a/djadmin2/tests/test_admin2tags.py +++ b/djadmin2/tests/test_admin2tags.py @@ -90,35 +90,3 @@ class TagsTests(TestCase): admin2_tags.formset_visible_fieldlist(formset), [u'Visible 1', u'Visible 2'] ) - - def test_get_attr_callable(self): - class Klass(object): - def hello(self): - return "hello" - - self.assertEquals( - admin2_tags.get_attr(Klass(), "hello"), - "hello" - ) - - def test_get_attr_str(self): - class Klass(object): - def __str__(self): - return "str" - - def __unicode__(self): - return "unicode" - - self.assertEquals( - admin2_tags.get_attr(Klass(), "__str__"), - "unicode" - ) - - def test_get_attr(self): - class Klass(object): - attr = "value" - - self.assertEquals( - admin2_tags.get_attr(Klass(), "attr"), - "value" - ) diff --git a/djadmin2/tests/test_utils.py b/djadmin2/tests/test_utils.py index 1cd6c60..8020ee9 100644 --- a/djadmin2/tests/test_utils.py +++ b/djadmin2/tests/test_utils.py @@ -135,3 +135,35 @@ class UtilsTest(TestCase): self.instance._meta.app_label, utils.model_app_label(self.instance) ) + + def test_get_attr_callable(self): + class Klass(object): + def hello(self): + return "hello" + + self.assertEquals( + utils.get_attr(Klass(), "hello"), + "hello" + ) + + def test_get_attr_str(self): + class Klass(object): + def __str__(self): + return "str" + + def __unicode__(self): + return "unicode" + + self.assertEquals( + utils.get_attr(Klass(), "__str__"), + "unicode" + ) + + def test_get_attr(self): + class Klass(object): + attr = "value" + + self.assertEquals( + utils.get_attr(Klass(), "attr"), + "value" + ) diff --git a/djadmin2/utils.py b/djadmin2/utils.py index 18a33f3..fc2f869 100644 --- a/djadmin2/utils.py +++ b/djadmin2/utils.py @@ -83,6 +83,19 @@ def model_app_label(obj): return model_options(obj).app_label +def get_attr(obj, attr): + """ + Get the right value for the attribute. Handle special cases like callables + and the __str__ attribute. + """ + if attr == '__str__': + value = unicode(obj) + else: + attribute = getattr(obj, attr) + value = attribute() if callable(attribute) else attribute + return value + + class NestedObjects(Collector): """ This is adopted from the Django core. django-admin2 mandates that code