django-modeltranslation
django-modeltranslation copied to clipboard
The MultilingualQuerySet class does not override annotation method
Consider the following case:
models.py file:
from django.db import models
class Object(models.Model):
name = models.CharField()
translation.py file:
from modeltranslation.translator import TranslationOptions, register
from .models import Object
@register(Object)
class ObjectTranslationOptions(TranslationOptions):
fields = ('name', )
fallback_languages = {'default': ('en-us',)}
Current bahavior:
from .models import Object
from django.utils import translation
from django.db.models import F
translation.activate("pt-br")
Object.objects.ceate(name_en_us='Test', name_pt_br='Teste')
print(Object.objects.first().name) # prints 'Teste'
print(Object.objects.annotate(test_name=F('name')).first().test_name) # prints 'Test'
The expected behavior should be:
print(Object.objects.annotate(test_name=F('name')).first().test_name) # prints 'Teste'
@CefasR I agree. I also encountered this issue. It would be awesome, if someone patched this. For now, since I also ran into this problem using F-expressions, I used this dirty hack:
from django.db.models.expressions import F
from django.utils.translation import get_language
class TranslatedF(F):
def resolve_expression(self, query=None, allow_joins=True, reuse=None,
summarize=False, for_save=False, simple_col=False):
lang = get_language().replace('-', '_')
name = self.name + '_' + lang
return query.resolve_ref(name, allow_joins, reuse, summarize, simple_col)
Then your annotation would oviously be:
print(Object.objects.annotate(test_name=TranslatedF('name')).first().test_name) # prints 'Teste'
I chose to override the F.resolve_expression method to delay the get_language call as much as possible to have a better chance to resolve properly. The easier way would have been to override the F.__init__ method and simply replace the self.name attribute with the language-specific field name, but then the language would have to be defined during the F-object's initialization.
Anyway, this worked for me in a specific situation.
I couldn't figure out, where to even begin with a "proper" patch. Hope someone more skilled gets on that.