mirror of
https://github.com/Hopiu/django-modeltranslation.git
synced 2026-05-02 18:44:43 +00:00
Handle related fields in field descriptor (work in progress, issue 36).
This commit is contained in:
parent
006239a68e
commit
5d5bf067ad
2 changed files with 56 additions and 22 deletions
|
|
@ -11,12 +11,11 @@ from modeltranslation.fields import (TranslationField,
|
|||
OneToOneTranslationField,
|
||||
ManyToManyTranslationField)
|
||||
from modeltranslation.utils import (TranslationFieldDescriptor,
|
||||
RelatedTranslationFieldDescriptor,
|
||||
ManyToManyTranslationFieldDescriptor,
|
||||
build_localized_fieldname)
|
||||
|
||||
|
||||
RELATED_CLASSES = ('ManyToOneRel', 'OneToOneRel', 'ManyToManyRel',)
|
||||
|
||||
|
||||
class AlreadyRegistered(Exception):
|
||||
pass
|
||||
|
||||
|
|
@ -68,7 +67,8 @@ def add_localized_fields(model):
|
|||
# django model fields and therefore adds them via add_to_class
|
||||
field = model._meta.get_field(field_name)
|
||||
field_class_name = field.rel.__class__.__name__
|
||||
if field_class_name in RELATED_CLASSES:
|
||||
if field_class_name in ('ManyToOneRel', 'OneToOneRel',
|
||||
'ManyToManyRel',):
|
||||
to = field.rel.to._meta.object_name
|
||||
if field_class_name == 'ManyToOneRel':
|
||||
translation_field = ForeignKeyTranslationField(\
|
||||
|
|
@ -176,11 +176,11 @@ class Translator(object):
|
|||
rev_dict[ln] = orig_name
|
||||
translation_opts.localized_fieldnames_rev = rev_dict
|
||||
|
||||
# TODO: Check if fallback_value is set to a type that the field
|
||||
# expects and raise ImproperlyConfigured in case it doesn't.
|
||||
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):
|
||||
|
|
@ -188,8 +188,19 @@ class Translator(object):
|
|||
None)
|
||||
else:
|
||||
field_fallback_value = model_fallback_values
|
||||
setattr(model, field_name, TranslationFieldDescriptor(field_name,
|
||||
fallback_value=field_fallback_value))
|
||||
|
||||
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)
|
||||
|
||||
#signals.pre_init.connect(translated_model_initializing, sender=model,
|
||||
#weak=False)
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ class TranslationFieldDescriptor(object):
|
|||
self.name = name
|
||||
self.val = initial_val
|
||||
self.fallback_value = fallback_value
|
||||
self.loc_field_name = ""
|
||||
|
||||
def __set__(self, instance, value):
|
||||
lang = get_language()
|
||||
|
|
@ -80,18 +81,40 @@ class TranslationFieldDescriptor(object):
|
|||
|
||||
def __get__(self, instance, owner):
|
||||
if not instance:
|
||||
raise ValueError(u"Translation field '%s' can only be "
|
||||
"accessed via an instance not via "
|
||||
"a class." % self.name)
|
||||
lang = get_language()
|
||||
loc_field_name = build_localized_fieldname(self.name, lang)
|
||||
# FIXME: KeyError raised by ForeignKeyTanslationField
|
||||
# in admin list view.
|
||||
try:
|
||||
name = instance.__dict__[self.name]
|
||||
except KeyError:
|
||||
return None
|
||||
if hasattr(instance, loc_field_name):
|
||||
return getattr(instance, loc_field_name) or\
|
||||
(name if self.fallback_value is None else\
|
||||
raise ValueError(u"Translation field '%s' can only be accessed "
|
||||
"via an instance not via a class." % self.name)
|
||||
self.loc_field_name = build_localized_fieldname(self.name,
|
||||
get_language())
|
||||
if hasattr(instance, self.loc_field_name):
|
||||
return getattr(instance, self.loc_field_name) or\
|
||||
(self.get_default_instance(instance) if\
|
||||
self.fallback_value is None else\
|
||||
self.fallback_value)
|
||||
|
||||
def get_default_instance(self, instance):
|
||||
"""
|
||||
Returns default instance of the field. Supposed to be overidden by
|
||||
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
|
||||
#instance_id = instance.__dict__['%s_id' % self.name]
|
||||
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
|
||||
|
|
|
|||
Loading…
Reference in a new issue