【问题标题】:Django prefetch related and django hvadDjango prefetch 相关和 django hvad
【发布时间】:2013-05-10 06:18:34
【问题描述】:

我有以下模型,我正在使用 django-hvad 进行翻译

class FooType(TranslatableModel):
    code = models.CharField(max_length=255, unique=True)
    translations = TranslatedFields(name=models.CharField(max_length=255))

    def __unicode__(self):
        return self.lazy_translation_getter('name')

任何时候我都要求提供酒店类型列表;

多次查询

SELECT ••• FROM "foo_footype_translation" WHERE "foo_foo_type_translation"."master_id" = 159 LIMIT 1

每当我调用 unicode 时,我都必须应用 prefetch_related。 有办法吗?

【问题讨论】:

    标签: django django-hvad


    【解决方案1】:

    编辑:从查看文档看来,您应该使用 TranslationManager

    from hvad.manager import TranslationManager
    
    class FooType(TranslatableModel):
        ...
    
        objects = TranslationManager()
    

    参考号:http://django-hvad.readthedocs.org/en/latest/public/queryset.html#translationqueryset

    【讨论】:

    • def get_query_set(self): return super(FooTypeManager,self).get_query_set().prefetch_related('translations') 在加载页面期间仍然进行 553 次查询
    • 在删除这些额外查询之前,您调用的 prefetch_related 表是什么
    • 我已经在使用它了,class FooTypeManager(TranslationManager): def get_query_set(self): return super(FooTypeManager, self).get_query_set().model.objects.language('en').select_related('translations__name')
    【解决方案2】:

    自从被问到这个问题已经有一段时间了,但由于没有得到明确的答案,有些事情已经改变,有些事情已经完善,我想我会添加一个。

    在 hvad 中使用可翻译对象的正常方法是请求同时获取翻译。您在README 页面和documentation 中有几个示例,但看起来像这样:

    qs = FooType.objects.language("en").all()
    

    以这种方式加载的对象将被完全加载,包括它们在给定语言中的翻译。过滤掉没有该语言翻译的对象。

    您可以省略语言以使用当前语言(与 Django 的 LocaleMiddleware 结合使用时最有用):

    qs = FooType.objects.language().all()
    

    您也可以透明地使用已翻译的字段,例如这将返回当前语言中名称为 foobar 的所有对象:

    qs = FooType.objects.language().filter(name__iexact='foobar')
    

    您还可以使用'all' 特殊代码一次搜索所有语言。以下行将返回任何语言的名称为foobar 的所有对象(对于每种匹配的语言,将返回具有多种语言的此类名称的对象一次):

    qs = FooType.objects.language('all').filter(name__iexact='foobar')
    

    如果您运行 Django 1.6 或更高版本,也可以使用给定语言请求对象列表,并使用基于优先级的后备列表,这样:

    qs = FooType.objects.language("de").fallbacks("ja", "en")
    

    这将获取所有对象,而不过滤任何对象。未翻译成德语的对象将以日语加载。如果它们在日语中不可用,那么接下来会尝试英语,如果它也不可用,则会选择任意语言(在内部,这使用自连接,因此只发出一个请求)。

    在任何情况下,要使用翻译后的字段而不产生性能损失,您必须通过language() 方法或make it implicit(仅限高级用户)。

    这种行为不是默认行为的原因是为了保持与现有代码库的兼容性:只要不调用language(),hvad 就不会触及您的查询。

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-12-15
      • 2017-05-01
      • 1970-01-01
      相关资源
      最近更新 更多