django-modeltrans icon indicating copy to clipboard operation
django-modeltrans copied to clipboard

Fallback behavior of virtual fields inconsistent with behavior when used in expressions

Open bbliem opened this issue 2 years ago • 0 comments

Assume you have the settings

LANGUAGE_CODE = "en"
MODELTRANS_FALLBACK = {"default": ("de",)},

and the following model instance:

blog = Blog.objects.create(title="foo")

The following example shows that the fallback behavior of TranslatedVirtualField.__get__() and TranslatedVirtualField.as_expression() is different, which is in my opinion not intuitive:

>>> with override("de"): print(blog.title_i18n)
foo
>>> with override("de"): print(Blog.objects.filter(id=blog.id).values("title_i18n"))
<MultilingualQuerySet [{'title_i18n': None}]>

This is because __get__() falls back to the original field value, whereas as_expression() only considers the languages in the fallback chain but not the original field value.

Adding the following before the Coalesce in as_expression() would fix that:

lookups.append(bare_lookup.replace(self.name, self.original_name))

This would, in addition, also fix the error that you get in as_expression() when you specify an empty fallback chain by MODELTRANS_FALLBACK = {"default": ()}:

ValueError: Coalesce must take at least two expressions

bbliem avatar May 12 '22 11:05 bbliem