Django __in 但 return 第一个匹配元素
Django __in but return the first matching element
我有这个型号
from django.db import models
class TranslatedString(models.Model):
lang = models.CharField()
key = models.CharField()
value = models.CharField()
我有这个模型的这些实例:
a = TranslatedString(lang="en_US", key="my-string", value="hello world")
b = TranslatedString(lang="en_AU", key="my-string", value="g'day world")
c = TranslatedString(lang="ja_JP", key="my-string", value="こんにちは世界")
我有这个用户想要的语言列表
preferred_langs = ["en_CA", "en_US", "en_AU", "fr_CA"]
按喜好排序。我想要 return 匹配该列表中第一项的值。即使 a
和 b
都匹配
这样的查询
TranslatedString.objects.filter(key="my-string", lang__in=preferred_langs).first()
我希望它按列表排序,这样我总是得到a
。
我可以查询preferred_langs
和return中的每个元素,只要找到匹配值就可以查询,但是有没有更好的选择?我想在一次查询中完成。
如果您不介意从数据库中检索所有首选翻译,这可以通过对 Python 中的模型进行排序来简洁地完成:
preferred_langs = ["en_CA", "en_US", "en_AU", "fr_CA"]
strings = list(TranslatedString.objects.filter(key="my-string", lang__in=preferred_langs))
strings.sort(key=lambda s: preferred_langs.index(s))
first_choice = strings[0]
print(first_choice.lang) # outputs "en_US"
这将执行单个(但可能很大)查询。但是,如果首选语言的序列相当短,排序的时间应该可以忽略不计。
您可以在 preferred_langs
上使用生成器表达式来生成首选语言到列表中各自索引的映射,作为 When
对象,以便将 Case
对象注释为一个字段,以便您可以按它对过滤结果进行排序:
from django.db.models import Case, Value, When
TranslatedString.objects.filter(key="my-string", lang__in=preferred_langs).annotate(
preference=Case(*(When(lang=lang, then=Value(i)) for i, lang in preferred_langs))
).order_by('preference').first()
我有这个型号
from django.db import models
class TranslatedString(models.Model):
lang = models.CharField()
key = models.CharField()
value = models.CharField()
我有这个模型的这些实例:
a = TranslatedString(lang="en_US", key="my-string", value="hello world")
b = TranslatedString(lang="en_AU", key="my-string", value="g'day world")
c = TranslatedString(lang="ja_JP", key="my-string", value="こんにちは世界")
我有这个用户想要的语言列表
preferred_langs = ["en_CA", "en_US", "en_AU", "fr_CA"]
按喜好排序。我想要 return 匹配该列表中第一项的值。即使 a
和 b
都匹配
TranslatedString.objects.filter(key="my-string", lang__in=preferred_langs).first()
我希望它按列表排序,这样我总是得到a
。
我可以查询preferred_langs
和return中的每个元素,只要找到匹配值就可以查询,但是有没有更好的选择?我想在一次查询中完成。
如果您不介意从数据库中检索所有首选翻译,这可以通过对 Python 中的模型进行排序来简洁地完成:
preferred_langs = ["en_CA", "en_US", "en_AU", "fr_CA"]
strings = list(TranslatedString.objects.filter(key="my-string", lang__in=preferred_langs))
strings.sort(key=lambda s: preferred_langs.index(s))
first_choice = strings[0]
print(first_choice.lang) # outputs "en_US"
这将执行单个(但可能很大)查询。但是,如果首选语言的序列相当短,排序的时间应该可以忽略不计。
您可以在 preferred_langs
上使用生成器表达式来生成首选语言到列表中各自索引的映射,作为 When
对象,以便将 Case
对象注释为一个字段,以便您可以按它对过滤结果进行排序:
from django.db.models import Case, Value, When
TranslatedString.objects.filter(key="my-string", lang__in=preferred_langs).annotate(
preference=Case(*(When(lang=lang, then=Value(i)) for i, lang in preferred_langs))
).order_by('preference').first()