diff --git a/polymorphic/showfields.py b/polymorphic/showfields.py index 6d1f6e1..fdb4bcf 100644 --- a/polymorphic/showfields.py +++ b/polymorphic/showfields.py @@ -1,9 +1,11 @@ # -*- coding: utf-8 -*- - +import django from django.db import models from django.utils import six +from django.utils.six import python_2_unicode_compatible +@python_2_unicode_compatible class ShowFieldBase(object): """ base class for the ShowField... model mixins, does the work """ @@ -11,6 +13,7 @@ class ShowFieldBase(object): polymorphic_showfield_type = False polymorphic_showfield_content = False + polymorphic_showfield_deferred = False # these may be overridden by the user polymorphic_showfield_max_line_width = None @@ -87,12 +90,12 @@ class ShowFieldBase(object): parts.append((False, out, ',')) - def __unicode__(self): + def __str__(self): # create list ("parts") containing one tuple for each title/field: # ( bool: new section , item-text , separator to use after item ) # start with model name - parts = [(True, self.__class__.__name__, ':')] + parts = [(True, self._meta.object_name, ':')] # add all regular fields self._showfields_add_regular_fields(parts) @@ -105,6 +108,11 @@ class ShowFieldBase(object): if hasattr(self, 'polymorphic_extra_select_names'): self._showfields_add_dynamic_fields(self.polymorphic_extra_select_names, 'Extra', parts) + if self.polymorphic_showfield_deferred: + fields = self.get_deferred_fields() + if fields: + parts.append((False, u"deferred[{0}]".format(",".join(sorted(fields))), '')) + # format result indent = len(self.__class__.__name__) + 5 @@ -142,6 +150,11 @@ class ShowFieldBase(object): return '<' + out + '>' + if django.VERSION < (1, 8): + def get_deferred_fields(self): + from django.db.models import DeferredAttribute + return set(attr for attr, value in self.__class__ if isinstance(value, DeferredAttribute)) + class ShowFieldType(ShowFieldBase): """ model mixin that shows the object's class and it's field types """ diff --git a/polymorphic/tests.py b/polymorphic/tests.py index 3a89b89..38ad70c 100644 --- a/polymorphic/tests.py +++ b/polymorphic/tests.py @@ -46,6 +46,7 @@ class PlainC(PlainB): class Model2A(ShowFieldType, PolymorphicModel): field1 = models.CharField(max_length=10) + polymorphic_showfield_deferred = True class Model2B(Model2A): @@ -562,18 +563,19 @@ class PolymorphicTests(TestCase): self.create_model2abcd() objects_deferred = Model2A.objects.defer('field1') - self.assertNotIn('field1', objects_deferred[0].__dict__, - 'field1 was not deferred (using defer())') + + self.assertNotIn('field1', objects_deferred[0].__dict__, 'field1 was not deferred (using defer())') self.assertEqual(repr(objects_deferred[0]), - '') + '') self.assertEqual(repr(objects_deferred[1]), - '') + '') self.assertEqual(repr(objects_deferred[2]), - '') + '') self.assertEqual(repr(objects_deferred[3]), - '') + '') objects_only = Model2A.objects.only('pk', 'polymorphic_ctype', 'field1') + self.assertIn('field1', objects_only[0].__dict__, 'qs.only("field1") was used, but field1 was incorrectly deferred') self.assertIn('field1', objects_only[3].__dict__, @@ -584,14 +586,13 @@ class PolymorphicTests(TestCase): self.assertEqual(repr(objects_only[0]), '') self.assertEqual(repr(objects_only[1]), - '') + '') self.assertEqual(repr(objects_only[2]), - '') + '') self.assertEqual(repr(objects_only[3]), - '') + '') # A bug in Django 1.4 prevents using defer across reverse relations # . Since polymorphic @@ -611,7 +612,7 @@ class PolymorphicTests(TestCase): self.assertEqual(repr(objects_deferred_field4[2]), '') self.assertEqual(repr(objects_deferred_field4[3]), - '') + '') objects_only_field4 = Model2A.objects.only( 'polymorphic_ctype', 'field1', @@ -625,7 +626,7 @@ class PolymorphicTests(TestCase): self.assertEqual(repr(objects_only_field4[2]), '') self.assertEqual(repr(objects_only_field4[3]), - '') + '') def test_manual_get_real_instance(self):