我有一个项目模型,它具有组模型的FK。组具有名称和两个其他字段:(bool)is_private指示组是否为私有,FK指向django.auth.models.Group以指示此项目组可见的组成员身份。
有100个项目,他们很快就会在不到1秒的时间内完成任务:
def project_list(request):
parameters = {field_name: value for field_name, value in request.GET.items() if value and field_name in project._meta.get_all_field_names()}
all_projects = project.objects.select_related().filter(**parameters)
return all_projects
只有一个项目有一个私人小组,一旦我添加隐私检查,获取它需要花费超过4秒的时间:
def project_list(request):
parameters = {field_name: value for field_name, value in request.GET.items() if value and field_name in project._meta.get_all_field_names()}
all_projects = project.objects.select_related().filter(**parameters)
for p in all_projects.filter(group__is_private = True):
if not request.user.groups.filter(name = p.group.private_group.name).exists():
all_projects = all_projects.exclude(id=p.id)
return all_projects
有没有办法重做这个以减少时间?
答案 0 :(得分:0)
在下面的代码中,您在每次迭代中都会获取单个group
,因此您需要进行大量数据库查询,从而减慢速度:
all_projects = project.objects.select_related().filter(**parameters)
for p in all_projects.filter(group__is_private = True):
if not request.user.groups.filter(name = p.group.private_group):
如果您想要仅在用户位于该组中的情况下获取没有私人组或私有组的项目,请使用:
from django.db.models import Q
def project_list(request):
parameters = {field_name: value for field_name, value in request.GET.items() if value and field_name in project._meta.get_all_field_names()}
group_ids = request.user.groups.values_list('id', flat=True)
all_projects = project.objects.select_related().filter(**parameters)
all_projects = all_projects.filter(Q(group__is_private=False) | Q(group__is_private=True, group_id__in=group_ids))
return all_projects