예제 #1
0
    def save(self, commit=True):
        if self.instance.pk is None:
            fail_message = 'created'
            new = True
        else:
            fail_message = 'changed'
            new = False
        super(TranslatableModelForm, self).save(True)
        trans_model = self.instance._meta.translations_model
        language_code = self.cleaned_data.get('language_code', get_language())
        if not new:
            trans = get_cached_translation(self.instance)
            if not trans:
                try:
                    trans = get_translation(self.instance, language_code)
                except trans_model.DoesNotExist:
                    trans = trans_model()
        else:
            trans = trans_model()

        trans.language_code = language_code
        trans.master = self.instance
        trans = save_instance(self, trans, self._meta.fields, fail_message,
                              commit, construct=True)
        return combine(trans)
예제 #2
0
 def _get_real_instances(self, base_results):
     """
     The logic for this method was taken from django-polymorphic by Bert
     Constantin (https://github.com/bconstantin/django_polymorphic) and was
     slightly altered to fit the needs of django-nani.
     """
     # get the primary keys of the shared model results
     base_ids = [obj.pk for obj in base_results]
     fallbacks = list(self._translation_fallbacks)
     # get all translations for the fallbacks chosen for those shared models,
     # note that this query is *BIG* and might return a lot of data, but it's
     # arguably faster than running one query for each result or even worse
     # one query per result per language until we find something
     translations_manager = self.model._meta.translations_model.objects
     baseqs = translations_manager.select_related("master")
     translations = baseqs.filter(language_code__in=fallbacks, master__pk__in=base_ids)
     fallback_objects = defaultdict(dict)
     # turn the results into a dict of dicts with shared model primary key as
     # keys for the first dict and language codes for the second dict
     for obj in translations:
         fallback_objects[obj.master.pk][obj.language_code] = obj
     # iterate over the share dmodel results
     for instance in base_results:
         translation = None
         # find the translation
         for fallback in fallbacks:
             translation = fallback_objects[instance.pk].get(fallback, None)
             if translation is not None:
                 break
         # if we found a translation, yield the combined result
         if translation:
             yield combine(translation)
         else:
             # otherwise yield the shared instance only
             yield instance
예제 #3
0
    def save(self, commit=True):
        if self.instance.pk is None:
            fail_message = 'created'
            new = True
        else:
            fail_message = 'changed'
            new = False
        super(TranslatableModelForm, self).save(True)
        trans_model = self.instance._meta.translations_model
        language_code = self.cleaned_data.get('language_code', get_language())
        if not new:
            trans = get_cached_translation(self.instance)
            if not trans or trans.language_code != language_code:
                try:
                    trans = get_translation(self.instance, language_code)
                except trans_model.DoesNotExist:
                    trans = trans_model()
        else:
            trans = trans_model()

        trans.language_code = language_code
        trans.master = self.instance
        trans = save_instance(self,
                              trans,
                              self._meta.fields,
                              fail_message,
                              commit,
                              construct=True)
        return combine(trans)
예제 #4
0
 def iterator(self):
     for obj in super(TranslationMixin, self).iterator():
         # non-cascade-deletion hack:
         if not obj.master:
             yield obj
         else:
             yield combine(obj)
예제 #5
0
 def _post_clean(self):
     if self.instance.pk:
         try:
             trans = trans = get_translation(self.instance, self.instance.language_code)
             trans.master = self.instance
             self.instance = combine(trans)
         except self.instance._meta.translations_model.DoesNotExist:
             language_code = self.cleaned_data.get('language_code', get_language())
             self.instance = self.instance.translate(language_code)
     return super(TranslatableModelForm, self)._post_clean()
예제 #6
0
 def _post_clean(self):
     if self.instance.pk:
         try:
             trans = trans = get_translation(self.instance,
                                             self.instance.language_code)
             trans.master = self.instance
             self.instance = combine(trans)
         except self.instance._meta.translations_model.DoesNotExist:
             language_code = self.cleaned_data.get('language_code',
                                                   get_language())
             self.instance = self.instance.translate(language_code)
     return super(TranslatableModelForm, self)._post_clean()
예제 #7
0
 def iterator(self):
     """
     If this queryset is not filtered by a language code yet, it should be
     filtered first by calling self.language.
     
     If someone doesn't want a queryset filtered by language, they should use
     Model.objects.untranslated()
     """
     if not self._language_code:
         for obj in self.language().iterator():
             yield obj
     else:
         for obj in super(TranslationQueryset, self).iterator():
             # non-cascade-deletion hack:
             if not obj.master:
                 yield obj
             else:
                 yield combine(obj)
예제 #8
0
 def iterator(self):
     """
     If this queryset is not filtered by a language code yet, it should be
     filtered first by calling self.language.
     
     If someone doesn't want a queryset filtered by language, they should use
     Model.objects.untranslated()
     """
     if not self._language_code:
         for obj in self.language().iterator():
             yield obj
     else:
         for obj in super(TranslationQueryset, self).iterator():
             # non-cascade-deletion hack:
             if not obj.master:
                 yield obj
             else:
                 yield combine(obj)
예제 #9
0
 def _get_real_instances(self, base_results):
     """
     The logic for this method was taken from django-polymorphic by Bert
     Constantin (https://github.com/bconstantin/django_polymorphic) and was
     slightly altered to fit the needs of django-nani.
     """
     # get the primary keys of the shared model results
     base_ids = [obj.pk for obj in base_results]
     fallbacks = list(self._translation_fallbacks)
     # get all translations for the fallbacks chosen for those shared models,
     # note that this query is *BIG* and might return a lot of data, but it's
     # arguably faster than running one query for each result or even worse
     # one query per result per language until we find something
     translations_manager = self.model._meta.translations_model.objects
     baseqs = translations_manager.select_related('master')
     translations = baseqs.filter(language_code__in=fallbacks,
                                  master__pk__in=base_ids)
     fallback_objects = defaultdict(dict)
     # turn the results into a dict of dicts with shared model primary key as
     # keys for the first dict and language codes for the second dict
     for obj in translations:
         fallback_objects[obj.master.pk][obj.language_code] = obj
     # iterate over the share dmodel results
     for instance in base_results:
         translation = None
         # find the translation
         for fallback in fallbacks:
             translation = fallback_objects[instance.pk].get(fallback, None)
             if translation is not None:
                 break
         # if we found a translation, yield the combined result
         if translation:
             yield combine(translation)
         else:
             # otherwise yield the shared instance only
             logger.error("no translation for %s, type %s" %
                          (instance, type(instance)))
예제 #10
0
 def __get__(self, instance, instance_type=None):
     if instance is None:
         return self
     value = super(ReverseTranslatedSingleRelatedObjectDescriptor, self).__get__(instance, instance_type)
     return combine(value)