【发布时间】:2020-07-01 08:42:32
【问题描述】:
我曾在 django 2.X 工作过。但我将在我的新项目中使用 django3.x。
在版本 2 中,我应该进行外部连接。我使用了prefetch_related 并过滤了prefetch_related 的模型。
在版本 2 中,如果我使用 prefetch_related,它将作为单个查询进行查询。但在版本 3 中,通过多个查询进行查询。
如果我只使用连接目标的 Q() 而不使用 prefetch_related,它在版本 3 中可以使用单个查询。
from django.db import models
from django.db.models import Q
from django.db.models import Prefetch
class Member(models.Model):
member_no = models.AutoField()
member_name = models.CharField()
class Permission(models.Model):
permission_no = models.AutoField()
class MemberPermission(models.Model):
member_permission_no = models.AutoField()
member_no = models.ForeignKey(
Member, related_name='members', on_delete=models.CASCADE,
)
permission_no = models.ForeignKey(
Permission, related_name='member_permissions', on_delete=models.CASCADE,
)
my_permission = Member.objects.prefetch_related('member_permissions').filter(Q(member_permissions__isnull=False))[:1]
print(my_permission[0].member_permissions)
# member outer join permission, single query at django 2.X
# member outer join permission & additional query at django 3.x
my_permission = Member.objects.filter(Q(member_permissions__isnull=False))[:1]
print(my_permission[0].member_permissions)
# member outer join permission, single query at django 3.X
my_permission = Member.objects.prefetch_related(
Prefetch('member_permissions', MemberPermission.objects.select_related(
'permission_no').all())
).filter(Q(members__isnull=False))[:1]
print(my_permission[0].member_permissions.all()[0].permission_no.permission_no)
# member outer join permission & additional query at django 3.x
如果我不使用prefetch_related,我可以获得单个查询。
但如果我想获得加入模型的模型(MemberPermission by Member 的权限),它不能。
我想知道如何在django3中通过Prefetch()查询一次。
【问题讨论】:
-
您是如何确定这是版本差异造成的?您是否创建了一个计算查询数量的测试,然后在 2 个不同的虚拟环境中运行它(使用 [tox](例如tox.readthedocs.io/en/latest)来显示问题?
-
@Melvyn 对不起,我犯了错误。我已经通过 venvs 再次尝试作为您的评论。它被执行为相同没有不同。如果我使用 '''prefetch_related''' 并尝试获取列,总是执行多个查询?
标签: django django-3.0