Django模型过滤器在一个项目上很慢

时间:2012-02-24 23:46:20

标签: django performance django-models django-queryset

我有一个项目模型,它具有组模型的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

有没有办法重做这个以减少时间?

1 个答案:

答案 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