diff --git a/CHANGES.rst b/CHANGES.rst index 8bde6b2..6648ca3 100644 --- a/CHANGES.rst +++ b/CHANGES.rst @@ -4,6 +4,8 @@ CHANGES tip (unreleased) ---------------- +- Fixed using SplitField on an abstract base model. + - Added pending-deprecation warnings for ``InheritanceCastModel``, ``manager_from``, and Django 1.1 support. Removed documentation for the deprecated utilities. Bumped ``ChoiceEnum`` from pending-deprecation to diff --git a/model_utils/fields.py b/model_utils/fields.py index de5db68..a52f96a 100644 --- a/model_utils/fields.py +++ b/model_utils/fields.py @@ -24,7 +24,7 @@ class AutoLastModifiedField(AutoCreatedField): A DateTimeField that updates itself on each save() of the model. By default, sets editable=False and default=datetime.now. - + """ def pre_save(self, model_instance, add): value = datetime.now() @@ -64,7 +64,7 @@ class MonitorField(models.DateTimeField): A DateTimeField that monitors another field on the same model and sets itself to the current date/time whenever the monitored field changes. - + """ def __init__(self, *args, **kwargs): kwargs.setdefault('default', datetime.now) @@ -82,7 +82,7 @@ class MonitorField(models.DateTimeField): def get_monitored_value(self, instance): return getattr(instance, self.monitor) - + def _save_initial(self, sender, instance, **kwargs): setattr(instance, self.monitor_attname, self.get_monitored_value(instance)) @@ -116,7 +116,7 @@ def get_excerpt(content): if line.strip() == SPLIT_MARKER: return '\n'.join(excerpt) excerpt.append(line) - + return '\n'.join(default_excerpt) class SplitText(object): @@ -143,7 +143,7 @@ class SplitText(object): def _get_has_more(self): return self.excerpt.strip() != self.content.strip() has_more = property(_get_has_more) - + # allows display via templates without .content necessary def __unicode__(self): return self.content @@ -176,9 +176,9 @@ class SplitField(models.TextField): # rules below. self.add_excerpt_field = not kwargs.pop('no_excerpt_field', False) super(SplitField, self).__init__(*args, **kwargs) - + def contribute_to_class(self, cls, name): - if self.add_excerpt_field: + if self.add_excerpt_field and not cls._meta.abstract: excerpt_field = models.TextField(editable=False) cls.add_to_class(_excerpt_field_name(name), excerpt_field) super(SplitField, self).contribute_to_class(cls, name) @@ -200,7 +200,7 @@ class SplitField(models.TextField): except AttributeError: return value - + # allow South to handle these fields smoothly try: from south.modelsinspector import add_introspection_rules diff --git a/model_utils/tests/models.py b/model_utils/tests/models.py index 1d93dd0..fb939e4 100644 --- a/model_utils/tests/models.py +++ b/model_utils/tests/models.py @@ -128,6 +128,15 @@ class Article(models.Model): +class SplitFieldAbstractParent(models.Model): + content = SplitField() + + + class Meta: + abstract = True + + + class NoRendered(models.Model): """ Test that the no_excerpt_field keyword arg works. This arg should diff --git a/model_utils/tests/tests.py b/model_utils/tests/tests.py index 9aaa065..816ccbe 100644 --- a/model_utils/tests/tests.py +++ b/model_utils/tests/tests.py @@ -21,7 +21,7 @@ from model_utils.tests.models import ( InheritanceManagerTestParent, InheritanceManagerTestChild1, InheritanceManagerTestChild2, TimeStamp, Post, Article, Status, StatusPlainTuple, TimeFrame, Monitored, StatusManagerAdded, - TimeFrameManagerAdded, Entry, Dude) + TimeFrameManagerAdded, Entry, Dude, SplitFieldAbstractParent) @@ -127,6 +127,16 @@ class SplitFieldTests(TestCase): self.assertEquals(f.value_to_string(self.post), self.full_text) + def test_abstract_inheritance(self): + class Child(SplitFieldAbstractParent): + pass + + self.assertEqual( + [f.name for f in Child._meta.fields], + ["id", "content", "_content_excerpt"]) + + + class MonitorFieldTests(TestCase): def setUp(self): self.instance = Monitored(name='Charlie')