Removed experimental support for related fields. The code is now available in a separate branch called django-modeltranslation-related-fields. To support related fields properly, deeper changes to the core of modeltranslation are required. These changes are beyond the scope of the next release.

This commit is contained in:
Dirk Eschler 2010-09-06 12:29:23 +00:00
parent 80d97888b0
commit f525e1e2c0
4 changed files with 15 additions and 618 deletions

View file

@ -7,13 +7,9 @@
(thanks to bmihelac, resolves issue 28)
ADDED: Setting to override the default language.
(thanks to jaap, resolves issue 2)
ADDED: Experimental support for related fields - ForeignKey,
ManyToManyField and OneToOneField.
(resolves issue 15)
CHANGED: Improved performance of update_translation_fields command.
(thanks to adamsc, resolves issue 43)
CHANGED: Custom fields are extended instead of overridden.
CHANGED: Factored out settings into a separate settings.py and consistently
used an app specific settings prefix.
CHANGED: Refactored creation of translation fields and added handling of

View file

@ -5,8 +5,6 @@ from warnings import warn
from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
from django.db.models.fields import Field, CharField, TextField
from django.db.models.fields.related import (ForeignKey, OneToOneField,
ManyToManyField)
from modeltranslation.settings import *
from modeltranslation.utils import (get_language,
@ -19,40 +17,21 @@ def create_translation_field(model, field_name, lang):
Translation field factory. Returns a ``TranslationField`` based on a
fieldname and a language.
Tries to create an object in the form ``'Translation%s' % cls_name``
(e.g. ``TranslationForeignKey``, ``TranslationManyToManyField``) based on
``model`` and ``field_name``. The class is usually a subclass of
``TranslationField`` and is supposed to be implemented in this module.
The list of supported fields can be extended. Just define a tuple of field
names in your settings.py like this::
The list of supported fields can be extended by defining a tuple of field
names in the projects settings.py like this::
MODELTRANSLATION_CUSTOM_FIELDS = ('MyField', 'MyOtherField',)
If the class is a subclass of CharField or TextField then the standard
``TranslationField`` will be used to instantiate the object. If the class
is neither a subclass of CharField or TextField, nor implemented here, nor
If the class is neither a subclass of CharField or TextField, nor
in ``CUSTOM_FIELDS`` an ``ImproperlyConfigured`` exception will be raised.
"""
field = model._meta.get_field(field_name)
cls_name = field.__class__.__name__
# No subclass required for text-like fields
if isinstance(field, (CharField, TextField)) or cls_name in CUSTOM_FIELDS:
return TranslationField(translated_field=field, language=lang)
# Try to instantiate translation field subclass
try:
translation_field = getattr(sys.modules['modeltranslation.fields'],
'Translation%s' % cls_name)
except AttributeError:
if not (isinstance(field, (CharField, TextField)) or\
cls_name in CUSTOM_FIELDS):
raise ImproperlyConfigured('%s is not supported by '
'modeltranslation.' % cls_name)
# Handle related fields
if cls_name in ('ForeignKey', 'OneToOneField', 'ManyToManyField'):
warn('Support for related fields is experimental and known to has '
'flaws. Only use it if you know what you are doing.',
FutureWarning)
return translation_field(translated_field=field, language=lang,
to=field.rel.to._meta.object_name)
return TranslationField(translated_field=field, language=lang)
@ -141,64 +120,6 @@ class TranslationField(Field):
return super(TranslationField, self).formfield(*args, **defaults)
class RelatedTranslationField(object):
"""
Mixin class which handles shared init of a translated relation field.
"""
def _related_pre_init(self, translated_field, language, *args, **kwargs):
self.translated_field = translated_field
self.language = language
self.field_name = self.translated_field.name
self.translated_field_name =\
build_localized_fieldname(self.translated_field.name,
self.language)
# Dynamically add a related_name to the original field
translated_field.rel.related_name =\
'%s%s' % (self.translated_field.model._meta.module_name,
self.field_name)
TranslationField.__init__(self, self.translated_field, self.language,
*args, **kwargs)
def _related_post_init(self):
# Dynamically add a related_name to the translation fields
self.rel.related_name =\
'%s%s' % (self.translated_field.model._meta.module_name,
self.translated_field_name)
# ForeignKey's init overrides some essential values from
# TranslationField, they have to be reassigned.
TranslationField._post_init(self, self.translated_field, self.language)
class TranslationForeignKey(ForeignKey, TranslationField,
RelatedTranslationField):
def __init__(self, translated_field, language, to, to_field=None, *args,
**kwargs):
self._related_pre_init(translated_field, language, *args, **kwargs)
ForeignKey.__init__(self, to, to_field, **kwargs)
self._related_post_init()
class TranslationOneToOneField(OneToOneField, TranslationField,
RelatedTranslationField):
def __init__(self, translated_field, language, to, to_field=None, *args,
**kwargs):
self._related_pre_init(translated_field, language, *args, **kwargs)
OneToOneField.__init__(self, to, to_field, **kwargs)
self._related_post_init()
class TranslationManyToManyField(ManyToManyField, TranslationField,
RelatedTranslationField):
def __init__(self, translated_field, language, to, *args, **kwargs):
self._related_pre_init(translated_field, language, *args, **kwargs)
ManyToManyField.__init__(self, to, **kwargs)
self._related_post_init()
class TranslationFieldDescriptor(object):
"""A descriptor used for the original translated field."""
def __init__(self, name, initial_val="", fallback_value=None):
@ -239,23 +160,3 @@ class TranslationFieldDescriptor(object):
related subclasses.
"""
return instance.__dict__[self.name]
class RelatedTranslationFieldDescriptor(TranslationFieldDescriptor):
def __init__(self, name, initial_val="", fallback_value=None):
TranslationFieldDescriptor.__init__(self, name, initial_val="",
fallback_value=None)
def get_default_instance(self, instance):
# TODO: Implement
pass
class ManyToManyTranslationFieldDescriptor(TranslationFieldDescriptor):
def __init__(self, name, initial_val="", fallback_value=None):
TranslationFieldDescriptor.__init__(self, name, initial_val="",
fallback_value=None)
def get_default_instance(self, instance):
# TODO: Implement
pass

View file

@ -29,25 +29,10 @@ class TestModel(models.Model):
url = models.URLField(verify_exists=False, blank=True, null=True)
email = models.EmailField(blank=True, null=True)
xml = models.XMLField(blank=True, null=True)
fk = models.ForeignKey(RelatedModel, blank=True, null=True)
o2o = models.OneToOneField(RelatedModel, blank=True, null=True)
m2m = models.ManyToManyField(RelatedModel, blank=True, null=True)
#boolean = models.BooleanField()
#nullboolean = models.NullBooleanField()
#integer = models.IntegerField(null=True)
#biginteger = models.BigIntegerField(null=True)
#positiveinteger = models.PositiveIntegerField(null=True)
#positivesmallinteger = models.PositiveSmallIntegerField(null=True)
#smallinteger = models.SmallIntegerField(null=True)
#csvinteger = models.CommaSeparatedIntegerField(max_length=255, null=True)
class TestTranslationOptions(translator.TranslationOptions):
fields = ('title', 'text', 'url', 'email', 'xml', 'fk', 'o2o', 'm2m',)
#fields = ('title', 'text', 'url', 'email', 'xml', 'boolean',
#'nullboolean', 'integer', 'biginteger', 'positiveinteger',
#'positivesmallinteger', 'smallinteger',
#'csvinteger',)
fields = ('title', 'text', 'url', 'email', 'xml',)
translator.translator._registry = {}
translator.translator.register(TestModel, TestTranslationOptions)
@ -59,25 +44,10 @@ class TestModelWithFallback(models.Model):
url = models.URLField(verify_exists=False, blank=True, null=True)
email = models.EmailField(blank=True, null=True)
xml = models.XMLField(blank=True, null=True)
fk = models.ForeignKey(RelatedModel, blank=True, null=True)
o2o = models.OneToOneField(RelatedModel, blank=True, null=True)
m2m = models.ManyToManyField(RelatedModel, blank=True, null=True)
#boolean = models.BooleanField()
#nullboolean = models.NullBooleanField()
#integer = models.IntegerField(null=True)
#biginteger = models.BigIntegerField(null=True)
#positiveinteger = models.PositiveIntegerField(null=True)
#positivesmallinteger = models.PositiveSmallIntegerField(null=True)
#smallinteger = models.SmallIntegerField(null=True)
#csvinteger = models.CommaSeparatedIntegerField(max_length=255, null=True)
class TestTranslationOptionsWithFallback(translator.TranslationOptions):
fields = ('title', 'text', 'url', 'email', 'xml', 'fk', 'o2o', 'm2m',)
#fields = ('title', 'text', 'url', 'email', 'xml', 'boolean',
#'nullboolean', 'integer', 'biginteger', 'positiveinteger',
#'positivesmallinteger', 'smallinteger',
#'csvinteger',)
fields = ('title', 'text', 'url', 'email', 'xml',)
fallback_values = ""
translator.translator.register(TestModelWithFallback,
@ -90,25 +60,10 @@ class TestModelWithFallback2(models.Model):
url = models.URLField(verify_exists=False, blank=True, null=True)
email = models.EmailField(blank=True, null=True)
xml = models.XMLField(blank=True, null=True)
fk = models.ForeignKey(RelatedModel, blank=True, null=True)
o2o = models.OneToOneField(RelatedModel, blank=True, null=True)
m2m = models.ManyToManyField(RelatedModel, blank=True, null=True)
#boolean = models.BooleanField()
#nullboolean = models.NullBooleanField()
#integer = models.IntegerField(null=True)
#biginteger = models.BigIntegerField(null=True)
#positiveinteger = models.PositiveIntegerField(null=True)
#positivesmallinteger = models.PositiveSmallIntegerField(null=True)
#smallinteger = models.SmallIntegerField(null=True)
#csvinteger = models.CommaSeparatedIntegerField(max_length=255, null=True)
class TestTranslationOptionsWithFallback2(translator.TranslationOptions):
fields = ('title', 'text', 'url', 'email', 'xml', 'fk', 'o2o', 'm2m',)
#fields = ('title', 'text', 'url', 'email', 'xml', 'boolean',
#'nullboolean', 'integer', 'biginteger', 'positiveinteger',
#'positivesmallinteger', 'smallinteger',
#'csvinteger',)
fields = ('title', 'text', 'url', 'email', 'xml',)
fallback_values = {'text': ugettext_lazy('Sorry, translation is not '
'available.')}
@ -170,39 +125,6 @@ class ModeltranslationTest(ModeltranslationTestBase):
self.failUnless('xml' in field_names)
self.failUnless('xml_de' in field_names)
self.failUnless('xml_en' in field_names)
self.failUnless('fk' in field_names)
self.failUnless('fk_de' in field_names)
self.failUnless('fk_en' in field_names)
self.failUnless('o2o' in field_names)
self.failUnless('o2o_de' in field_names)
self.failUnless('o2o_en' in field_names)
self.failUnless('m2m' in field_names)
self.failUnless('m2m_de' in field_names)
self.failUnless('m2m_en' in field_names)
#self.failUnless('boolean' in field_names)
#self.failUnless('boolean_de' in field_names)
#self.failUnless('boolean_en' in field_names)
#self.failUnless('nullboolean' in field_names)
#self.failUnless('nullboolean_de' in field_names)
#self.failUnless('nullboolean_en' in field_names)
#self.failUnless('integer' in field_names)
#self.failUnless('integer_de' in field_names)
#self.failUnless('integer_en' in field_names)
#self.failUnless('biginteger' in field_names)
#self.failUnless('biginteger_de' in field_names)
#self.failUnless('biginteger_en' in field_names)
#self.failUnless('positiveinteger' in field_names)
#self.failUnless('positiveinteger_de' in field_names)
#self.failUnless('positiveinteger_en' in field_names)
#self.failUnless('positivesmallinteger' in field_names)
#self.failUnless('positivesmallinteger_de' in field_names)
#self.failUnless('positivesmallinteger_en' in field_names)
#self.failUnless('smallinteger' in field_names)
#self.failUnless('smallinteger_de' in field_names)
#self.failUnless('smallinteger_en' in field_names)
#self.failUnless('csvinteger' in field_names)
#self.failUnless('csvinteger_de' in field_names)
#self.failUnless('csvinteger_en' in field_names)
inst.delete()
def test_verbose_name(self):
@ -391,79 +313,6 @@ class ModeltranslationTestRule1(ModeltranslationTestBase):
value_de='<?xml version="1.0" encoding="UTF-8" ?><foo>bar</foo>',
value_en='<?xml version="1.0" encoding="UTF-8" ?><foo>baz</foo>')
def test_rule1_foreignkey(self):
rel1 = RelatedModel.objects.create(reltitle='German related title')
rel2 = RelatedModel.objects.create(reltitle='English related title')
self._test_field(field_name='fk',
value_de=rel1,
value_en=rel2)
def test_rule1_onetoone_field(self):
# TODO: Required custom field test
rel1 = RelatedModel.objects.create(reltitle='German related title')
rel2 = RelatedModel.objects.create(reltitle='English related title')
self._test_field(field_name='o2o',
value_de=rel1,
value_en=rel2)
def test_rule1_manytomany_field(self):
# TODO: Required custom field test
rel1 = RelatedModel.objects.create(reltitle='German related title')
rel2 = RelatedModel.objects.create(reltitle='English related title')
self._test_field(field_name='m2m',
value_de=rel1,
value_en=rel2)
#def test_rule1_boolean_field(self):
#self._test_field(field_name='boolean',
#value_de=True,
#value_en=False,
#deactivate=False)
## Now with swapped values
#self._test_field(field_name='boolean',
#value_de=False,
#value_en=True)
#def test_rule1_nullboolean_field(self):
#self._test_field(field_name='nullboolean',
#value_de=True,
#value_en=False,
#deactivate=False)
## Now with swapped values
#self._test_field(field_name='nullboolean',
#value_de=False,
#value_en=True)
#def test_rule1_integer_field(self):
#self._test_field(field_name='integer',
#value_de=42,
#value_en=-42)
#def test_rule1_biginteger_field(self):
#self._test_field(field_name='biginteger',
#value_de=1234567890,
#value_en=-1234567890)
#def test_rule1_positiveinteger_field(self):
#self._test_field(field_name='positiveinteger',
#value_de=23,
#value_en=42)
#def test_rule1_positivesmallinteger_field(self):
#self._test_field(field_name='positivesmallinteger',
#value_de=1,
#value_en=2)
#def test_rule1_smallinteger_field(self):
#self._test_field(field_name='smallinteger',
#value_de=1,
#value_en=-1)
#def test_rule1_csvinteger_field(self):
#self._test_field(field_name='csvinteger',
#value_de='1,2,3,4,5',
#value_en='5,4,3,2,1')
class ModeltranslationTestRule2(ModeltranslationTestBase):
"""
@ -556,110 +405,6 @@ class ModeltranslationTestRule2(ModeltranslationTestBase):
value2='<?xml version="1.0" encoding="UTF-8" ?><bar>foo</bar>',
value3='<?xml version="1.0" encoding="UTF-8" ?><baz>foo</baz>')
def test_rule2_foreignkey(self):
rel1_de = RelatedModel.objects.create(reltitle='German related title')
rel1_en = RelatedModel.objects.create(reltitle='English related title')
rel2 = RelatedModel.objects.create(reltitle='Related title2')
rel3 = RelatedModel.objects.create(reltitle='Related title3')
self._test_field(field_name='fk',
value1_de=rel1_de,
value1_en=rel1_en,
value2=rel2,
value3=rel3)
def test_rule2_onetoone_field(self):
rel1_de = RelatedModel.objects.create(reltitle='German related title')
rel1_en = RelatedModel.objects.create(reltitle='English related title')
rel2 = RelatedModel.objects.create(reltitle='Related title2')
rel3 = RelatedModel.objects.create(reltitle='Related title3')
self._test_field(field_name='o2o',
value1_de=rel1_de,
value1_en=rel1_en,
value2=rel2,
value3=rel3)
def test_rule2_manytomany_field(self):
# TODO: Required custom field test
rel1_de = RelatedModel.objects.create(reltitle='German related title')
rel1_en = RelatedModel.objects.create(reltitle='English related title')
rel2 = RelatedModel.objects.create(reltitle='Related title2')
rel3 = RelatedModel.objects.create(reltitle='Related title3')
self._test_field(field_name='m2m',
value1_de=rel1_de,
value1_en=rel1_en,
value2=rel2,
value3=rel3)
#def test_rule2_boolean_field(self):
#self._test_field(field_name='boolean',
#value1_de=True,
#value1_en=False,
#value2=True,
#value3=False,
#deactivate=False)
## Now with swapped values
#self._test_field(field_name='boolean',
#value1_de=False,
#value1_en=True,
#value2=False,
#value3=True)
#def test_rule2_nullboolean_field(self):
#self._test_field(field_name='nullboolean',
#value1_de=True,
#value1_en=False,
#value2=True,
#value3=False,
#deactivate=False)
## Now with swapped values
#self._test_field(field_name='nullboolean',
#value1_de=False,
#value1_en=True,
#value2=False,
#value3=True)
#def test_rule2_integer_field(self):
#self._test_field(field_name='integer',
#value1_de=42,
#value1_en=-42,
#value2=23,
#value3=32)
#def test_rule2_biginteger_field(self):
#self._test_field(field_name='biginteger',
#value1_de=1234567890,
#value1_en=-1234567890,
#value2=987654321,
#value3=-987654321)
#def test_rule2_positiveinteger_field(self):
#self._test_field(field_name='positiveinteger',
#value1_de=23,
#value1_en=42,
#value2=123,
#value3=321)
#def test_rule2_positivesmallinteger_field(self):
#self._test_field(field_name='positivesmallinteger',
#value1_de=1,
#value1_en=2,
#value2=3,
#value3=4)
#def test_rule2_smallinteger_field(self):
#self._test_field(field_name='smallinteger',
#value1_de=1,
#value1_en=-1,
#value2=2,
#value3=-2)
#def test_rule2_csvinteger_field(self):
#self._test_field(field_name='csvinteger',
#value1_de='1,2,3,4,5',
#value1_en='5,4,3,2,1',
#value2='6,7,8',
#value3='9,8,10')
class ModeltranslationTestRule3(ModeltranslationTestBase):
"""
@ -745,110 +490,6 @@ class ModeltranslationTestRule3(ModeltranslationTestBase):
value2='<?xml version="1.0" encoding="UTF-8" ?><bar>foo</bar>',
value3='<?xml version="1.0" encoding="UTF-8" ?><baz>foo</baz>')
def test_rule3_foreignkey(self):
rel1_de = RelatedModel.objects.create(reltitle='German related title')
rel1_en = RelatedModel.objects.create(reltitle='English related title')
rel2 = RelatedModel.objects.create(reltitle='Related title2')
rel3 = RelatedModel.objects.create(reltitle='Related title3')
self._test_field(field_name='fk',
value1_de=rel1_de,
value1_en=rel1_en,
value2=rel2,
value3=rel3)
def test_rule3_onetoone_field(self):
rel1_de = RelatedModel.objects.create(reltitle='German related title')
rel1_en = RelatedModel.objects.create(reltitle='English related title')
rel2 = RelatedModel.objects.create(reltitle='Related title2')
rel3 = RelatedModel.objects.create(reltitle='Related title3')
self._test_field(field_name='o2o',
value1_de=rel1_de,
value1_en=rel1_en,
value2=rel2,
value3=rel3)
def test_rule3_manytomany_field(self):
# TODO: Required custom field test
rel1_de = RelatedModel.objects.create(reltitle='German related title')
rel1_en = RelatedModel.objects.create(reltitle='English related title')
rel2 = RelatedModel.objects.create(reltitle='Related title2')
rel3 = RelatedModel.objects.create(reltitle='Related title3')
self._test_field(field_name='m2m',
value1_de=rel1_de,
value1_en=rel1_en,
value2=rel2,
value3=rel3)
#def test_rule3_boolean_field(self):
#self._test_field(field_name='boolean',
#value1_de=True,
#value1_en=False,
#value2=True,
#value3=False,
#deactivate=False)
## Now with swapped values
#self._test_field(field_name='boolean',
#value1_de=False,
#value1_en=True,
#value2=False,
#value3=True)
#def test_rule3_nullboolean_field(self):
#self._test_field(field_name='nullboolean',
#value1_de=True,
#value1_en=False,
#value2=True,
#value3=False,
#deactivate=False)
## Now with swapped values
#self._test_field(field_name='nullboolean',
#value1_de=False,
#value1_en=True,
#value2=False,
#value3=True)
#def test_rule3_integer_field(self):
#self._test_field(field_name='integer',
#value1_de=42,
#value1_en=-42,
#value2=23,
#value3=32)
#def test_rule3_biginteger_field(self):
#self._test_field(field_name='biginteger',
#value1_de=1234567890,
#value1_en=-1234567890,
#value2=987654321,
#value3=-987654321)
#def test_rule3_positiveinteger_field(self):
#self._test_field(field_name='positiveinteger',
#value1_de=23,
#value1_en=42,
#value2=123,
#value3=321)
#def test_rule3_positivesmallinteger_field(self):
#self._test_field(field_name='positivesmallinteger',
#value1_de=1,
#value1_en=2,
#value2=3,
#value3=4)
#def test_rule3_smallinteger_field(self):
#self._test_field(field_name='smallinteger',
#value1_de=1,
#value1_en=-1,
#value2=2,
#value3=-2)
#def test_rule3_csvinteger_field(self):
#self._test_field(field_name='csvinteger',
#value1_de='1,2,3,4,5',
#value1_en='5,4,3,2,1',
#value2='6,7,8',
#value3='9,8,10')
class ModeltranslationTestRule4(ModeltranslationTestBase):
"""
@ -942,126 +583,6 @@ class ModeltranslationTestRule4(ModeltranslationTestBase):
value2_en='<?xml version="1.0" encoding="UTF-8" ?><baz>foo</baz>',
value3='<?xml version="1.0" encoding="UTF-8" ?><baz>bar</baz>')
def test_rule4_foreignkey(self):
rel1_de = RelatedModel.objects.create(reltitle='German related title')
rel1_en = RelatedModel.objects.create(reltitle='English related title')
rel2_de = RelatedModel.objects.create(reltitle='Rel German title2')
rel2_en = RelatedModel.objects.create(reltitle='Rel English title2')
rel3 = RelatedModel.objects.create(reltitle='Rel title3')
self._test_field(field_name='fk',
value1_de=rel1_de,
value1_en=rel1_en,
value2_de=rel2_de,
value2_en=rel2_en,
value3=rel3)
def test_rule4_onetoone_field(self):
rel1_de = RelatedModel.objects.create(reltitle='German related title')
rel1_en = RelatedModel.objects.create(reltitle='English related title')
rel2_de = RelatedModel.objects.create(reltitle='Rel German title2')
rel2_en = RelatedModel.objects.create(reltitle='Rel English title2')
rel3 = RelatedModel.objects.create(reltitle='Rel title3')
self._test_field(field_name='o2o',
value1_de=rel1_de,
value1_en=rel1_en,
value2_de=rel2_de,
value2_en=rel2_en,
value3=rel3)
def test_rule4_manytomany_field(self):
# TODO: Required custom field test
rel1_de = RelatedModel.objects.create(reltitle='German related title')
rel1_en = RelatedModel.objects.create(reltitle='English related title')
rel2_de = RelatedModel.objects.create(reltitle='Rel German title2')
rel2_en = RelatedModel.objects.create(reltitle='Rel English title2')
rel3 = RelatedModel.objects.create(reltitle='Rel title3')
self._test_field(field_name='m2m',
value1_de=rel1_de,
value1_en=rel1_en,
value2_de=rel2_de,
value2_en=rel2_en,
value3=rel3)
#def test_rule4_boolean_field(self):
#self._test_field(field_name='boolean',
#value1_de=True,
#value1_en=False,
#value2_de=True,
#value2_en=False,
#value3=True,
#deactivate=False)
## Now with swapped values
#self._test_field(field_name='boolean',
#value1_de=False,
#value1_en=True,
#value2_de=False,
#value2_en=True,
#value3=True)
#def test_rule4_nullboolean_field(self):
#self._test_field(field_name='nullboolean',
#value1_de=True,
#value1_en=False,
#value2_de=True,
#value2_en=False,
#value3=True,
#deactivate=False)
## Now with swapped values
#self._test_field(field_name='nullboolean',
#value1_de=False,
#value1_en=True,
#value2_de=False,
#value2_en=True,
#value3=False)
#def test_rule4_integer_field(self):
#self._test_field(field_name='integer',
#value1_de=42,
#value1_en=-42,
#value2_de=23,
#value2_en=32,
#value3=33)
#def test_rule4_biginteger_field(self):
#self._test_field(field_name='biginteger',
#value1_de=1234567890,
#value1_en=-1234567890,
#value2_de=987654321,
#value2_en=-987654321,
#value3=987654322)
#def test_rule4_positiveinteger_field(self):
#self._test_field(field_name='positiveinteger',
#value1_de=23,
#value1_en=42,
#value2_de=123,
#value2_en=321,
#value3=322)
#def test_rule4_positivesmallinteger_field(self):
#self._test_field(field_name='positivesmallinteger',
#value1_de=1,
#value1_en=2,
#value2_de=3,
#value2_en=4,
#value3=5)
#def test_rule4_smallinteger_field(self):
#self._test_field(field_name='smallinteger',
#value1_de=1,
#value1_en=-1,
#value2_de=2,
#value2_en=-2,
#value3=3)
#def test_rule4_csvinteger_field(self):
#self._test_field(field_name='csvinteger',
#value1_de='1,2,3,4,5',
#value1_en='5,4,3,2,1',
#value2_de='6,7,8',
#value2_en='9,8,10',
#value3='9,8,10,11')
class ModeltranslationTestModelValidation(ModeltranslationTestBase):
"""

View file

@ -1,18 +1,12 @@
# -*- coding: utf-8 -*-
from django.conf import settings
#from django.contrib.contenttypes.models import ContentType
from django.db import models
from django.db.models import signals
from django.db.models.base import ModelBase
from django.utils.functional import curry
from modeltranslation.fields import (TranslationField,
TranslationForeignKey,
TranslationOneToOneField,
TranslationManyToManyField,
TranslationFieldDescriptor,
RelatedTranslationFieldDescriptor,
ManyToManyTranslationFieldDescriptor,
create_translation_field)
from modeltranslation.utils import build_localized_fieldname
@ -36,9 +30,7 @@ class TranslationOptions(object):
on.
"""
def __init__(self, *args, **kwargs):
# self.translation_model = None
#self.model_ct = None
self.localized_fieldnames = list()
self.localized_fieldnames = []
def add_localized_fields(model):
@ -160,31 +152,18 @@ class Translator(object):
rev_dict[ln] = orig_name
translation_opts.localized_fieldnames_rev = rev_dict
model_fallback_values = getattr(translation_opts, 'fallback_values',
None)
model_fallback_values =\
getattr(translation_opts, 'fallback_values', None)
for field_name in translation_opts.fields:
# TODO: Check if fallback_value is set to a type that the field
# expects and raise ImproperlyConfigured in case it doesn't.
if model_fallback_values is None:
field_fallback_value = None
elif isinstance(model_fallback_values, dict):
field_fallback_value = model_fallback_values.get(field_name,
None)
field_fallback_value =\
model_fallback_values.get(field_name, None)
else:
field_fallback_value = model_fallback_values
field = model._meta.get_field(field_name)
field_class_name = field.rel.__class__.__name__
if field_class_name in ('ManyToOneRel', 'OneToOneRel'):
descriptor = RelatedTranslationFieldDescriptor(field_name,
fallback_value=field_fallback_value)
elif field_class_name == 'ManyToManyRel':
descriptor = ManyToManyTranslationFieldDescriptor(field_name,
fallback_value=field_fallback_value)
else:
descriptor = TranslationFieldDescriptor(field_name,
fallback_value=field_fallback_value)
setattr(model, field_name, descriptor)
setattr(model, field_name, TranslationFieldDescriptor(field_name,\
fallback_value=field_fallback_value))
#signals.pre_init.connect(translated_model_initializing, sender=model,
#weak=False)