使用 django-modeltranslation 进行语言独立查询
language independent query with django-modeltranslation
我目前开始在 Django 应用程序中使用 django-modeltranslation,我想进行查询以检索模型的实例,与系统中设置的语言无关。
例如我有以下模型:
class Product(models.Model):
description = models.CharField(max_length=200)
sku = models.CharField(unique=True, null=False, max_length=30)
price = models.DecimalField(max_digits=8, decimal_places=2)
以及 translation.py 中的以下内容:
class ProductTranslationOptions(TranslationOptions):
fields = ('description', 'sku')
translator.register(Product, ProductTranslationOptions)
和 Django 设置:
gettext = lambda s: s
LANGUAGES = (
('en', gettext('English')),
('de', gettext('German')),
)
MODELTRANSLATION_LANGUAGES = ('en', 'de')
MODELTRANSLATION_DEFAULT_LANGUAGE = 'en'
MODELTRANSLATION_FALLBACK_LANGUAGES = ('en',)
让我们创建一个产品实例:
Product.objects.create(description_en='product en', description_de='product de', sku_en='sku-001', sku_de='sku-002', price=10.0)
现在我想找到带有 sku sku-002
的实例,以检索产品的价格(与语言无关)。
Product.objects.filter(sku='sku-002')
然而这 returns 一个空的 MultilingualQuerySet
。
只有以下 returns 是正确的 Product 实例。
Product.objects.filter(sku_de='sku-002')
或
from django.utils import translation
translation.activate('de')
Product.objects.filter(sku='sku-002')
我想这是 django-modeltranslation 的预期行为,但有时找到一个独立于语言的实例是可行的。
一个解决方案可能是遍历所有 LANGUAGES
并尝试找到每种语言的实例:
from django.conf import settings
LANGUAGES = list(getattr(settings,
'MODELTRANSLATION_LANGUAGES',
(l[0] for l in settings.LANGUAGES)))
def find_product_by_sku(sku):
for language in LANGUAGES:
product = Product.objects.filter(**{"sku_{}".format(language): sku})
if product:
return product
但这不是很实用,特别是对于现有的应用程序,需要在多个地方调整代码。有没有办法直接使用查询集管理器来检索独立于语言的实例?
看这里:
它看起来像当前的行为(在查询期间不支持回退)。
在 Whosebug link 中推荐这可以帮助一点:.filter(Q(title_de = 'hello') | Q(title_en = 'hello'))
你可以看看对所有语言一起使用 postgres jsonb 字段的包(django-modeltrans,django-nece)是否更好地支持这一点。我没有测试过任何东西,但我在 django-modeltrans 阅读了关于“_i18n”和 django-nece 中的其他支持。
我目前开始在 Django 应用程序中使用 django-modeltranslation,我想进行查询以检索模型的实例,与系统中设置的语言无关。 例如我有以下模型:
class Product(models.Model):
description = models.CharField(max_length=200)
sku = models.CharField(unique=True, null=False, max_length=30)
price = models.DecimalField(max_digits=8, decimal_places=2)
以及 translation.py 中的以下内容:
class ProductTranslationOptions(TranslationOptions):
fields = ('description', 'sku')
translator.register(Product, ProductTranslationOptions)
和 Django 设置:
gettext = lambda s: s
LANGUAGES = (
('en', gettext('English')),
('de', gettext('German')),
)
MODELTRANSLATION_LANGUAGES = ('en', 'de')
MODELTRANSLATION_DEFAULT_LANGUAGE = 'en'
MODELTRANSLATION_FALLBACK_LANGUAGES = ('en',)
让我们创建一个产品实例:
Product.objects.create(description_en='product en', description_de='product de', sku_en='sku-001', sku_de='sku-002', price=10.0)
现在我想找到带有 sku sku-002
的实例,以检索产品的价格(与语言无关)。
Product.objects.filter(sku='sku-002')
然而这 returns 一个空的 MultilingualQuerySet
。
只有以下 returns 是正确的 Product 实例。
Product.objects.filter(sku_de='sku-002')
或
from django.utils import translation
translation.activate('de')
Product.objects.filter(sku='sku-002')
我想这是 django-modeltranslation 的预期行为,但有时找到一个独立于语言的实例是可行的。
一个解决方案可能是遍历所有 LANGUAGES
并尝试找到每种语言的实例:
from django.conf import settings
LANGUAGES = list(getattr(settings,
'MODELTRANSLATION_LANGUAGES',
(l[0] for l in settings.LANGUAGES)))
def find_product_by_sku(sku):
for language in LANGUAGES:
product = Product.objects.filter(**{"sku_{}".format(language): sku})
if product:
return product
但这不是很实用,特别是对于现有的应用程序,需要在多个地方调整代码。有没有办法直接使用查询集管理器来检索独立于语言的实例?
看这里:
它看起来像当前的行为(在查询期间不支持回退)。
在 Whosebug link 中推荐这可以帮助一点:
.filter(Q(title_de = 'hello') | Q(title_en = 'hello'))
你可以看看对所有语言一起使用 postgres jsonb 字段的包(django-modeltrans,django-nece)是否更好地支持这一点。我没有测试过任何东西,但我在 django-modeltrans 阅读了关于“_i18n”和 django-nece 中的其他支持。