def localize_fields(cls, localized_fields): """ For each field name in localized_fields, for each language in settings.LANGUAGES, add fields to cls, and remove the original field, instead replace it with a DefaultFieldDescriptor, which always returns the field in the current language. """ # never do this twice if hasattr(cls, 'localized_fields'): return cls # MSGID_LANGUAGE is the language that is used for the gettext message id's. # If it is not available, because the site isn't using subsites, the # LANGUAGE_CODE is good too. MSGID_LANGUAGE gives the opportunity to # specify a language not available in the site but which is still used for # the message id's. msgid_language = getattr(settings, 'MSGID_LANGUAGE', settings.LANGUAGE_CODE) # set the localized fields property cls.localized_fields = localized_fields for field in localized_fields: original_attr = get_field_from_model_by_name(cls, field) for cnt, language_code in enumerate(get_all_language_codes()): i18n_attr = copy.copy(original_attr) # add support for south introspection. i18n_attr._south_introspects = True i18n_attr.original_fieldname = field i18n_attr.include_in_xml = False lang_attr_name = get_real_fieldname(field, language_code) i18n_attr.name = lang_attr_name i18n_attr.creation_counter = i18n_attr.creation_counter + .01 * cnt # null must be allowed for the message id language because this # language might not be available at all in the backend if not i18n_attr.null and i18n_attr.default is NOT_PROVIDED: i18n_attr.null = True if language_code != msgid_language: # no validation for the fields that are language specific if not i18n_attr.blank: i18n_attr.blank = True if i18n_attr.verbose_name: i18n_attr.verbose_name = translation.string_concat( i18n_attr.verbose_name, u' (%s)' % language_code) cls.add_to_class(lang_attr_name, i18n_attr) # delete original field del cls._meta.local_fields[cls._meta.local_fields.index(original_attr)] # copy some values and functions from the original_attr # so the field can emulate the original_attr as good as possible kwargs = { 'serialize': getattr(original_attr, 'serialize', True), 'extra_attrs': getattr(original_attr, 'extra_attrs', None), 'max_length': getattr(original_attr, 'max_length', None), 'min_length': getattr(original_attr, 'min_length', None), 'form_field': original_attr.formfield(**FORMFIELD_FOR_DBFIELD_DEFAULTS.get( original_attr.__class__, {})), 'get_internal_type': original_attr.get_internal_type, 'unique': getattr(original_attr, 'unique', False), 'to_python': original_attr.to_python, } # copy __serialize__ if it was defined on the original attr if hasattr(original_attr, '__serialize__'): kwargs['__serialize__'] = original_attr.__serialize__ # add the DefaultFieldDescriptor where the original_attr was. cls.add_to_class(field, DefaultFieldDescriptor(field, **kwargs)) # update fields cache cls._meta._fill_fields_cache() # return the finished product return cls
def __restoreBlank(self, cls, blankFlags): for field, blank in zip(self.localizedFields, blankFlags): for code in get_all_language_codes(): i18n_attr = get_field_from_model_by_name( cls, getLocalizedFieldName(field, code)) i18n_attr.blank = blank
def __collectBlank(self, cls): blankFlags = [] for field in self.localizedFields: attr = get_field_from_model_by_name(cls, field) blankFlags.append(attr.blank) return blankFlags
def localize_fields(cls, localized_fields): """ For each field name in localized_fields, for each language in settings.LANGUAGES, add fields to cls, and remove the original field, instead replace it with a DefaultFieldDescriptor, which always returns the field in the current language. """ # never do this twice if hasattr(cls, 'localized_fields'): return cls # MSGID_LANGUAGE is the language that is used for the gettext message id's. # If it is not available, because the site isn't using subsites, the # LANGUAGE_CODE is good too. MSGID_LANGUAGE gives the opportunity to # specify a language not available in the site but which is still used for # the message id's. msgid_language = getattr(settings, 'MSGID_LANGUAGE', settings.LANGUAGE_CODE) # set the localized fields property cls.localized_fields = localized_fields for field in localized_fields: original_attr = get_field_from_model_by_name(cls, field) for cnt, language_code in enumerate(get_all_language_codes()): i18n_attr = copy.copy(original_attr) # add support for south introspection. i18n_attr._south_introspects = True i18n_attr.original_fieldname = field i18n_attr.include_in_xml = False lang_attr_name = get_real_fieldname(field, language_code) i18n_attr.name = lang_attr_name i18n_attr.creation_counter = i18n_attr.creation_counter + .01 * cnt # null must be allowed for the message id language because this # language might not be available at all in the backend if not i18n_attr.null and i18n_attr.default is NOT_PROVIDED: i18n_attr.null = True if language_code != msgid_language: # no validation for the fields that are language specific if not i18n_attr.blank: i18n_attr.blank = True if i18n_attr.verbose_name: i18n_attr.verbose_name = translation.string_concat( i18n_attr.verbose_name, u' (%s)' % language_code) cls.add_to_class(lang_attr_name, i18n_attr) # delete original field del cls._meta.local_fields[cls._meta.local_fields.index(original_attr)] # copy some values and functions from the original_attr # so the field can emulate the original_attr as good as possible kwargs = { 'serialize': getattr(original_attr, 'serialize', True), 'extra_attrs': getattr(original_attr, 'extra_attrs', None), 'max_length': getattr(original_attr, 'max_length', None), 'min_length': getattr(original_attr, 'min_length', None), 'form_field': original_attr.formfield( **FORMFIELD_FOR_DBFIELD_DEFAULTS.get( original_attr.__class__, {})), 'get_internal_type': original_attr.get_internal_type, 'unique': getattr(original_attr, 'unique', False), 'to_python': original_attr.to_python, } # copy __serialize__ if it was defined on the original attr if hasattr(original_attr, '__serialize__'): kwargs['__serialize__'] = original_attr.__serialize__ # add the DefaultFieldDescriptor where the original_attr was. cls.add_to_class(field, DefaultFieldDescriptor(field, **kwargs)) # update fields cache try: cls._meta._fill_fields_cache() except AttributeError: # Django 1.8 removed _fill_fields_cache cls._meta._expire_cache() cls._meta._get_fields(reverse=False) # return the finished product return cls
def __restoreBlank(self, cls, blankFlags): for field, blank in zip(self.localizedFields, blankFlags): for code in get_all_language_codes(): i18n_attr = get_field_from_model_by_name(cls, getLocalizedFieldName(field, code)) i18n_attr.blank = blank