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