关于函数'prefetch_related'的'* lookups'参数的变种
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了关于函数'prefetch_related'的'* lookups'参数的变种相关的知识,希望对你有一定的参考价值。
我无法弄清楚prefetch_related('arg_set')和prefetch_related('arg')之间的区别。
当使用参数'arg'even'arg_set'有效时,有时prefetch_related不起作用。
我搜索过docs.djangoproject.com,但至少我在下面的两个页面都找不到相关文档。 https://docs.djangoproject.com/en/2.1/ref/models/querysets/ https://docs.djangoproject.com/ja/2.1/ref/contrib/contenttypes/
你们有些人可以详细说明这些差异吗?我想阅读与此问题相关的官方文档,以便向我展示参考链接。
先感谢您。
环境:windows10,python 3.7.2,django 2.1.8,sqlite3,PyCham 2019.1。
views.朋友
from django.shortcuts import render
from .models import Article
def index(request):
a = Article.objects.all().select_related('user').prefetch_related('comment_set').order_by('id') # [1]
a = Article.objects.all().select_related('user').prefetch_related('comment').order_by('id') # [2]
return render(request,
'sns/index.html',
{'articles': a})
models.朋友
from django.db import models
from article_comment_model.settings import AUTH_USER_MODEL
class Article(models.Model):
user = models.ForeignKey(AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='article_user')
title = models.CharField(max_length=100)
text = models.TextField()
class Comment(models.Model):
user = models.ForeignKey(AUTH_USER_MODEL, on_delete=models.CASCADE, related_name='comment_user')
article = models.ForeignKey(Article, on_delete=models.CASCADE)
text = models.TextField()
我想了解各种prefetch_related参数。
callig prefetch_related()
的论据将是关系的名称。在你的情况下,这将是一个反向的ForeignKey
关系。正如你在documentation中看到的那样,反向关系的名称将是FOO_set
,其中FOO
是模型的小写名称。
因此在你的例子中prefetch_related('comment_set')
应该是正确的。如果你要指定related_name
之类的
article = models.ForeignKey(Article, on_delete=models.CASCADE,
related_name='comments')
related_name
将被用来代替FOO_set
,因此在这种情况下prefetch_related('comments')
应该是有效的。
在prefetch_related
中使用的查找名称取决于几个问题的答案:
- 是您在查询的模型上还是在关系的另一侧定义了关系?
如果在您要查询的模型上定义了关系(由Django文档称为“前向关系”),则查找只是字段名称。如果关系是在关系的另一端定义的(“向后关系”),那么查找取决于第二个问题:
- 您是否在定义关系的其他模型中定义了
related_name
?
如果是,查找是related_name
。如果没有related_name
,Django使用默认名称,modelname_set
用于x对多关系,modelname
用于x对一关系(均为小写)。
实际上,这意味着您的代码中包含以下内容:
- x对多关系:
# no related names defined, using default manager name
Article.objects.prefetch_related('comment_set')
# using related names
User.objects.prefetch_related('article_user', 'comment_user')
- x对一关系:
Article.objects.prefetch_related('user')
Comment.objects.prefetch_related('article', 'user')
使用prefetch_related
进行x-to-one关系就像上面的最后两个例子一样很少见。我们主要使用select_related
,因为后者只在原始查询中创建连接,而不是发出单独的查询。然而,正如你可以读到它的documentation的结尾,prefetch_related
有一些潜在的优势。它可以:
- 获取已过滤的查询集
- 获取不完整的模型(通过
only
和defer
) - 通过
Prefetch
对象执行嵌套预取
以上是关于关于函数'prefetch_related'的'* lookups'参数的变种的主要内容,如果未能解决你的问题,请参考以下文章
实例具体解释Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化
转 实例详解Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化
Django框架详细介绍---ORM相关操作---select_related和prefetch_related函数对 QuerySet 查询的优化
详解Django的 select_related 和 prefetch_related 函数对 QuerySet 查询的优化