made SplitField compatible with South FakeORM

This commit is contained in:
Carl Meyer 2010-01-31 10:54:36 -05:00
parent 81f47ba745
commit 9147becfc9
5 changed files with 52 additions and 5 deletions

View file

@ -100,10 +100,19 @@ class SplitDescriptor(object):
obj.__dict__[self.field.name] = value
class SplitField(models.TextField):
def __init__(self, *args, **kwargs):
# for South FakeORM compatibility: the frozen version of a
# SplitField can't try to add an _excerpt field, because the
# _excerpt field itself is frozen as well. See introspection
# 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):
excerpt_field = models.TextField(editable=False)
excerpt_field.creation_counter = self.creation_counter+1
cls.add_to_class(_excerpt_field_name(name), excerpt_field)
if self.add_excerpt_field:
excerpt_field = models.TextField(editable=False)
excerpt_field.creation_counter = self.creation_counter+1
cls.add_to_class(_excerpt_field_name(name), excerpt_field)
super(SplitField, self).contribute_to_class(cls, name)
setattr(cls, self.name, SplitDescriptor(self))
@ -127,7 +136,14 @@ class SplitField(models.TextField):
# allow South to handle these fields smoothly
try:
from south.modelsinspector import add_introspection_rules
add_introspection_rules(patterns=['model_utils\.fields\.'])
# For a normal MarkupField, the add_excerpt_field attribute is
# always True, which means no_excerpt_field arg will always be
# True in a frozen MarkupField, which is what we want.
add_introspection_rules(rules=[((SplitField,),
[],
{'no_excerpt_field': ('add_excerpt_field',
{})})],
patterns=['model_utils\.fields\.'])
except ImportError:
pass

View file

@ -34,3 +34,11 @@ class Article(models.Model):
def __unicode__(self):
return self.title
class NoRendered(models.Model):
"""
Test that the no_excerpt_field keyword arg works. This arg should
never be used except by the South model-freezing.
"""
body = SplitField(no_excerpt_field=True)

View file

@ -13,7 +13,7 @@ from django.conf import settings
def runtests():
test_runner = get_runner(settings)
failures = test_runner([], verbosity=1, interactive=True)
failures = test_runner(['tests'], verbosity=1, interactive=True)
sys.exit(failures)
if __name__ == '__main__':

View file

@ -9,3 +9,10 @@ INSTALLED_APPS = (
)
DATABASE_ENGINE = 'sqlite3'
try:
import south
INSTALLED_APPS += ('south',)
except ImportError:
pass

View file

@ -1,5 +1,7 @@
from django.test import TestCase
from django.conf import settings
from django.contrib.contenttypes.models import ContentType
from django.db.models.fields import FieldDoesNotExist
from model_utils import ChoiceEnum
from model_utils.fields import get_excerpt
@ -138,3 +140,17 @@ class QueryManagerTests(TestCase):
def testOrdering(self):
qs = Post.public_reversed.all()
self.assertEquals([p.order for p in qs], [5, 4, 1, 0])
if 'south' in settings.INSTALLED_APPS:
class SouthFreezingTests(TestCase):
def test_introspector_adds_no_excerpt_field(self):
from south.modelsinspector import introspector
mf = Article._meta.get_field('body')
args, kwargs = introspector(mf)
self.assertEquals(kwargs['no_excerpt_field'], 'True')
def test_no_excerpt_field_works(self):
from models import NoRendered
self.assertRaises(FieldDoesNotExist,
NoRendered._meta.get_field,
'_body_excerpt')