我正在为多语言网站使用 django 模型翻译。
直接读取属性时,语言回退效果很好。例如,如果当前语言是德语并且我打印 object.title,如果未定义德语标题,我将看到英文标题。
我希望回退也适用于查询,但事实并非如此。事实上,如果我做类似的事情
results = MyModel.objects.filter(title = 'hello')
如果未设置德语标题,这将不会得到任何结果,而我希望它返回带有英文标题“hello”的对象。
我怎样才能使这项工作?
提前致谢。
我正在为多语言网站使用 django 模型翻译。
直接读取属性时,语言回退效果很好。例如,如果当前语言是德语并且我打印 object.title,如果未定义德语标题,我将看到英文标题。
我希望回退也适用于查询,但事实并非如此。事实上,如果我做类似的事情
results = MyModel.objects.filter(title = 'hello')
如果未设置德语标题,这将不会得到任何结果,而我希望它返回带有英文标题“hello”的对象。
我怎样才能使这项工作?
提前致谢。
这里要做的是显式地查询期望的语言。在你的情况下:
from django.db.models import Q
# ...
# define your query like this:
results = MyModel.objects.filter(Q(title_de = 'hello') | Q(title_en = 'hello'))
# supposing you have German and English languages set
为什么这个工作?因为当您查询特定语言时,ModelTranslation 会保留它。否则它使用当前语言。
我希望它有帮助!
您必须确保您的模型已在 translation.py 中注册
from modeltranslation.translator import register, TranslationOptions
@register(YourModel)
class YourModel(TranslationOptions):
pass
这样,所有完成的查询都将根据其语言返回适当的字段,这是因为要注册它会创建一个 MultilingualManager
不幸的是,上面的答案是错误的。正确处理这种情况的方法是
查询集 = 查询集.filter( Q( Q(Q(title_fr_fr__icontains=search) & ~Q(title_fr_fr="")) | Q(Q(title_en_gb__icontains=search) & Q(title_fr_fr="")) ) )
其中 fr-fr - 是我们现在使用的语言,而 en-gb - 是我们的默认语言。这意味着让我们获得目标语言标题包含可搜索字符串且目标语言标题为填充(非空)或默认语言标题包含可搜索字符串且目标语言标题为空的那些行。
所以整个例子看起来像这样:
from django.db.models import Q
###
default_lang = settings.LANGUAGE_CODE.replace("-", "_")
current_lang = get_language().replace("-", "_")
queryset = queryset.filter(
Q(
Q(Q(**{f'title_{current_lang}__icontains': search}) & ~Q(**{f'title_{current_lang}': ""}))
|
Q(Q(**{f'title_{default_lang}__icontains': search}) & Q(**{f'title_{current_lang}': ""}))
)
)
azuax answer 在某些情况下会给出错误的结果。假设 title_de = 'ABC',title_en = 'DEF' 和当前语言 de。对于搜索字符串“DEF”,我们得到了这一行,但不应该因为用户看到“ABC”