Django-parler多数据库下翻译模型存储与检索问题求助
编辑于2023年8月:该问题已被彻底调查,可通过Pull Request #340修复。
问题
我在使用Django-parler时,遇到了多数据库场景下翻译模型查询异常的问题:
模型定义
class InstrumentFamily(TranslatableModel): primary_key = True translations = TranslatedFields( label=CharNullField(_('Label'), max_length=100, unique=False, null=True,)
环境与操作
我配置了default和test两个数据库别名,数据库路由默认将InstrumentFamily模型指向test库:
- 向
test库存储数据:fam = InstrumentFamily(code=TEST_CODE) with switch_language(fam, 'en'): fam.label = "test_family_test EN" with switch_language(fam, 'fr'): fam.label = "test_family_test FR" fam.save() - 向
default库存储数据:fam = InstrumentFamily(code="TEST_FAM") with switch_language(fam, 'en'): fam.label = "test_family_default_EN" with switch_language(fam, 'fr'): fam.label = "test_family_default_FR" fam.save(using='default')
异常现象
存储操作正常,但从default库读取对象时:
fam = InstrumentFamily.objects.using('default').get(code=TEST_CODE) print(f" label: {fam.label}")
主对象能从default库正确获取,但翻译数据却从test库查询,SQL追踪如下:
SELECT "orchestra_instrumentfamily"."id", "orchestra_instrumentfamily"."code" FROM "orchestra_instrumentfamily" WHERE "orchestra_instrumentfamily"."code" = 'TEST_FAM' LIMIT 21; args=('TEST_FAM',); alias=default SELECT "orchestra_instrumentfamily_translation"."id", "orchestra_instrumentfamily_translation"."language_code", "orchestra_instrumentfamily_translation"."label", "orchestra_instrumentfamily_translation"."master_id" FROM "orchestra_instrumentfamily_translation" WHERE ("orchestra_instrumentfamily_translation"."master_id" = 34 AND "orchestra_instrumentfamily_translation"."language_code" = 'en') LIMIT 21; args=(34, 'en'); alias=test
我想知道如何让using("default")的配置传递到翻译数据的查询中?这是不是Django-parler不支持的场景?
解决方案
官方修复
编辑于2023年8月:该问题已被官方彻底调查,可通过合并Pull Request #340中的代码完成修复,修复后Django-parler会自动将主查询的using参数传递给翻译模型的查询。
临时 workaround(修复前)
为翻译模型配置数据库路由:
为自动生成的InstrumentFamilyTranslation模型单独编写数据库路由规则,使其根据主模型的数据库选择逻辑匹配对应的库。手动加载翻译数据:
查询主对象后,显式指定翻译模型的数据库别名并加载翻译:fam = InstrumentFamily.objects.using('default').get(code=TEST_CODE) # 手动从default库获取翻译 translations = fam.get_translations_manager().using('default').filter(master_id=fam.pk) # 将翻译存入对象缓存,避免后续自动查询错误库 fam._translations_cache = {t.language_code: t for t in translations}
内容的提问来源于stack exchange,提问作者Alain Baudhuin
相关产品推荐
相关产品推荐

