web/lib/modeltranslation/utils.py
changeset 5 10b1f6d8a5d2
equal deleted inserted replaced
4:b77683731f25 5:10b1f6d8a5d2
       
     1 from django.db import models
       
     2 from django.conf import settings
       
     3 from django.core.exceptions import ValidationError
       
     4 from django.contrib.contenttypes.models import ContentType
       
     5 from django.utils.translation import get_language
       
     6 
       
     7 class TranslationFieldDescriptor(object):
       
     8     """
       
     9     A descriptor used for the original translated field.
       
    10     """
       
    11     def __init__(self, name, initial_val=""):
       
    12         """
       
    13         The ``name`` is the name of the field (which is not available in the
       
    14         descriptor by default - this is Python behaviour).
       
    15         """
       
    16         self.name = name        
       
    17         self.val = initial_val
       
    18 
       
    19     def __set__(self, instance, value):                
       
    20         # print "Descriptor.__set__%s %s %s.%s: %s" % (id(instance), id(self), type(instance), self.name, value)
       
    21         lang = get_language()              
       
    22         loc_field_name = build_localized_fieldname(self.name, lang)
       
    23         
       
    24         # also update the translation field of the current language        
       
    25         setattr(instance, loc_field_name, value)
       
    26         
       
    27         # update the original field via the __dict__ to prevent calling the
       
    28         # descriptor
       
    29         instance.__dict__[self.name] = value
       
    30         
       
    31 
       
    32     def __get__(self, instance, owner):
       
    33         # print "Descriptor.__get__%s %s %s.%s: %s" % (id(instance), id(self), type(instance), self.name, self.val)
       
    34         if not instance:
       
    35             raise ValueError(u"Translation field '%s' can only be "\
       
    36                                 "accessed via an instance not via "\
       
    37                                 "a class." % self.name)
       
    38         
       
    39         lang = get_language()                
       
    40         loc_field_name = build_localized_fieldname(self.name, lang) 
       
    41         if hasattr(instance, loc_field_name):            
       
    42             return getattr(instance, loc_field_name) or instance.__dict__[self.name]
       
    43         return instance.__dict__[self.name]             
       
    44         
       
    45 
       
    46 #def create_model(name, fields=None, app_label='', module='', options=None, admin_opts=None):
       
    47     #"""
       
    48     #Create specified model.
       
    49     #This is taken from http://code.djangoproject.com/wiki/DynamicModels
       
    50     #"""
       
    51     #class Meta:
       
    52         ## Using type('Meta', ...) gives a dictproxy error during model creation
       
    53         #pass
       
    54 
       
    55     #if app_label:
       
    56         ## app_label must be set using the Meta inner class
       
    57         #setattr(Meta, 'app_label', app_label)
       
    58 
       
    59     ## Update Meta with any options that were provided
       
    60     #if options is not None:
       
    61         #for key, value in options.iteritems():
       
    62             #setattr(Meta, key, value)
       
    63 
       
    64     ## Set up a dictionary to simulate declarations within a class
       
    65     #attrs = {'__module__': module, 'Meta': Meta}
       
    66 
       
    67     ## Add in any fields that were provided
       
    68     #if fields:
       
    69         #attrs.update(fields)
       
    70 
       
    71     ## Create the class, which automatically triggers ModelBase processing
       
    72     #model = type(name, (models.Model,), attrs)
       
    73 
       
    74     ## Create an Admin class if admin options were provided
       
    75     #if admin_opts is not None:
       
    76         #class Admin(admin.ModelAdmin):
       
    77             #pass
       
    78         #for key, value in admin_opts:
       
    79             #setattr(Admin, key, value)
       
    80         #admin.site.register(model, Admin)
       
    81 
       
    82     #return model
       
    83    
       
    84    
       
    85 def copy_field(field):
       
    86     """Instantiate a new field, with all of the values from the old one, except the    
       
    87     to and to_field in the case of related fields.
       
    88     
       
    89     This taken from http://www.djangosnippets.org/snippets/442/
       
    90     """    
       
    91     base_kw = dict([(n, getattr(field,n, '_null')) for n in models.fields.Field.__init__.im_func.func_code.co_varnames])
       
    92     if isinstance(field, models.fields.related.RelatedField):
       
    93         rel = base_kw.get('rel')
       
    94         rel_kw = dict([(n, getattr(rel,n, '_null')) for n in rel.__init__.im_func.func_code.co_varnames])
       
    95         if isinstance(field, models.fields.related.ForeignKey):
       
    96             base_kw['to_field'] = rel_kw.pop('field_name')
       
    97         base_kw.update(rel_kw)
       
    98     base_kw.pop('self')    
       
    99     return field.__class__(**base_kw)
       
   100         
       
   101 
       
   102 def build_localized_fieldname(field_name, lang):
       
   103     return '%s_%s' % (field_name, lang)