|
5
|
1 |
|
|
|
2 |
from django.conf import settings |
|
|
3 |
from django.db.models.fields import Field, CharField |
|
|
4 |
from django.utils.translation import get_language |
|
|
5 |
|
|
|
6 |
from modeltranslation.utils import build_localized_fieldname |
|
|
7 |
|
|
|
8 |
class TranslationField(Field): |
|
|
9 |
""" |
|
|
10 |
The translation field functions as a proxy to the original field which is |
|
|
11 |
wrapped. |
|
|
12 |
|
|
|
13 |
For every field defined in the model's ``TranslationOptions`` localized |
|
|
14 |
versions of that field are added to the model depending on the languages |
|
|
15 |
given in ``settings.LANGUAGES``. |
|
|
16 |
|
|
|
17 |
If for example there is a model ``News`` with a field ``title`` which is |
|
|
18 |
registered for translation and the ``settings.LANGUAGES`` contains the |
|
|
19 |
``de`` and ``en`` languages, the fields ``title_de`` and ``title_en`` will |
|
|
20 |
be added to the model class. These fields are realized using this |
|
|
21 |
descriptor. |
|
|
22 |
|
|
|
23 |
The translation field needs to know which language it contains therefore |
|
|
24 |
that needs to be specified when the field is created. |
|
|
25 |
""" |
|
|
26 |
def __init__(self, translated_field, language, *args, **kwargs): |
|
|
27 |
# Store the originally wrapped field for later |
|
|
28 |
self.translated_field = translated_field |
|
|
29 |
self.language = language |
|
|
30 |
|
|
|
31 |
# Update the dict of this field with the content of the original one |
|
|
32 |
# This might be a bit radical?! Seems to work though... |
|
|
33 |
self.__dict__.update(translated_field.__dict__) |
|
|
34 |
|
|
|
35 |
# Translation are always optional (for now - maybe add some parameters |
|
|
36 |
# to the translation options for configuring this) |
|
|
37 |
self.null = True |
|
|
38 |
self.blank = True |
|
|
39 |
|
|
|
40 |
# Adjust the name of this field to reflect the language |
|
|
41 |
self.attname = build_localized_fieldname(translated_field.name, language) |
|
|
42 |
self.name = self.attname |
|
|
43 |
|
|
|
44 |
# Copy the verbose name and append a language suffix (will e.g. in the |
|
|
45 |
# admin). This might be a proxy function so we have to check that here. |
|
|
46 |
if hasattr(translated_field.verbose_name, '_proxy____unicode_cast'): |
|
|
47 |
verbose_name = translated_field.verbose_name._proxy____unicode_cast() |
|
|
48 |
else: |
|
|
49 |
verbose_name = translated_field.verbose_name |
|
|
50 |
self.verbose_name = '%s [%s]' % (verbose_name, language) |
|
|
51 |
|
|
|
52 |
def pre_save(self, model_instance, add): |
|
|
53 |
val = super(TranslationField, self).pre_save(model_instance, add) |
|
|
54 |
if get_language() == self.language and not add: |
|
|
55 |
# Rule is: 3. Assigning a value to a translation field of the default language |
|
|
56 |
# also updates the original field |
|
|
57 |
model_instance.__dict__[self.translated_field.name] = val |
|
|
58 |
#setattr(model_instance, self.attname, orig_val) |
|
|
59 |
# Also return the original value |
|
|
60 |
#return orig_val |
|
|
61 |
return val |
|
|
62 |
|
|
|
63 |
#def get_attname(self): |
|
|
64 |
#return self.attname |
|
|
65 |
|
|
|
66 |
def get_internal_type(self): |
|
|
67 |
return self.translated_field.get_internal_type() |
|
|
68 |
|
|
|
69 |
def contribute_to_class(self, cls, name): |
|
|
70 |
|
|
|
71 |
super(TranslationField, self).contribute_to_class(cls, name) |
|
|
72 |
|
|
|
73 |
#setattr(cls, 'get_%s_display' % self.name, curry(cls._get_FIELD_display, field=self)) |
|
|
74 |
|
|
|
75 |
#class CurrentLanguageField(CharField): |
|
|
76 |
#def __init__(self, **kwargs): |
|
|
77 |
#super(CurrentLanguageField, self).__init__(null=True, max_length=5, **kwargs) |
|
|
78 |
|
|
|
79 |
#def contribute_to_class(self, cls, name): |
|
|
80 |
#super(CurrentLanguageField, self).contribute_to_class(cls, name) |
|
|
81 |
#registry = CurrentLanguageFieldRegistry() |
|
|
82 |
#registry.add_field(cls, self) |
|
|
83 |
|
|
|
84 |
|
|
|
85 |
#class CurrentLanguageFieldRegistry(object): |
|
|
86 |
#_registry = {} |
|
|
87 |
|
|
|
88 |
#def add_field(self, model, field): |
|
|
89 |
#reg = self.__class__._registry.setdefault(model, []) |
|
|
90 |
#reg.append(field) |
|
|
91 |
|
|
|
92 |
#def get_fields(self, model): |
|
|
93 |
#return self.__class__._registry.get(model, []) |
|
|
94 |
|
|
|
95 |
#def __contains__(self, model): |
|
|
96 |
#return model in self.__class__._registry |
|
|
97 |
|
|
|
98 |
|