问题 在Django中使用select_related选择特定字段


我有两个模型文章和博客相关使用外键。我想在提取文章时只选择博客名称。

articles = Articles.objects.all().select_related('blog__name')

生成的查询显示它选择了Blog模型中的所有字段。 我尝试使用select()和defer()与select_related,但两个都没有成功。

articles = Articles.objects.all().select_related('blog__name').only('blog__name', 'title', 'create_time')

上述查询导致错误:select_related中给出的字段名称无效:选项为:blog

如何生成查询以便仅选择文章字段和博客名称?


8513
2018-02-20 13:57


起源

我不认为这是可能的 - 文件 only 不要显示任何遍历关系的例子,而文档为 select_related 仅显示遍历多个关系的示例(即 rel__rel不是 rel__field)。看起来你能做的最好 articles = Articles.objects.all().select_related('blog').only('blog', 'title', 'create_time') - Anentropic
这样做的目的是什么?性能优化?但是,你可以使用它 prefetch_related,但这样你最终会得到2个查询而不是1个。 Articles.objects.all().prefetch_related(Prefetch('blog', queryset=Blog.objects.all().only('name'))) - Todor
唯一的目的是优化性能。我已经在使用select_related,但它提供了消耗大量内存的所有属性。有没有其他方法可以做到这一点? - RA123
截至此日期,对于django 1.8.9,我无法找到使用'defer'或'only'与'select_related'或类似的返回查询集的解决方案。 - RA123


答案:


您可以使用 注释() 为了这。

>>> a = Articles.objects.annotate(blog_name=F('blog__name')).first()
>>> a.title
>>> a.blog_name

9
2017-08-11 10:37





select_related 应该在整个模型上使用,然后你可以更多地过滤它。这将有效:

Articles.objects.select_related('blog').only('blog__name', 'title', 'create_time')

7
2018-02-20 18:44



使用.values返回字典而不是queryset对象,这使得在模板或视图中使用“file.url”或“file.name”之类的关系变得毫无用处。还有其他方法吗? - RA123
@ RA123我编辑了我的答案。试过它,这种方式对我有用 - T. Opletal
这也行不通。我在使用Django 1.8。它给出了以下错误 - “select_related:'blog'中给出的无效字段名称。选项是:博客”当我从'only'中的'blog__name'中删除'__name'时,它可以正常工作但是获取所有字段。 - RA123
它正在使用1.10,我正在使用它 QuerySet.defer(), 谢谢! - lechup