Django的。使用.all()查询从相关表中获取值,而无需重新查询数据库

时间:2018-08-13 23:30:51

标签: django django-models django-orm

快速警告-我对Django,Web开发和编程一般还是陌生的,所以我完全希望自己做一些愚蠢的事情。我遇到了一个问题,我查询数据库太多次,导致重复50次。我希望能够执行一个大型查询,以获取所有结果,然后根据需要从该查询中进行提取。我已经尝试过使这种情况发生,但是我似乎无法弄清楚如何在我的预取查询中指定一个值,而无需再次调用该查询。

我的理解是.all()不一定在声明时调用查询,我猜这是我的问题,但是我不确定。这是我的代码:

qs = Employees.objects.all().select_related(
            'employee', 'team', 'department', 'manager')
for p in periods:
    period, range, score, subject = p
    current_team = current_department = current_manager = None
    try:
        user = qs.get(employee_id=subject)
        current_team = user.team
        current_department = user.department
        current_manager = user.manager.username
        subject = user.employee.username
    except (User.DoesNotExist, Employees.DoesNotExist):
        subject = User.objects.get(id=subject).username

3 个答案:

答案 0 :(得分:0)

想出了一个解决方案:决定将qs变成一个立即获取它的列表,然后遍历该列表以不再执行任何查询:

qs = list(Employees.objects.all().select_related('employee', 'team', 'department', 'manager'))

for q in qs:
    if subject == q.employee_id:
        current_team = q.team
        current_department = q.department
        current_manager = q.manager.username
        subject = q.employee.username
    else:
        subject = subject

答案 1 :(得分:0)

您遇到了n+1问题。

为一对多关系获取相关记录并避免出现n+1问题的django方法是使用select_related

https://docs.djangoproject.com/en/dev/ref/models/querysets/#select-related

没有select_related

访问数据库。

e = Entry.objects.get(id=5)

再次访问数据库以获取相关的Blog对象。

b = e.blog

使用select_related

访问数据库。

e = Entry.objects.select_related('blog').get(id=5)

不打数据库,因为e.blog已预先填充 在上一个查询中。

b = e.blog

答案 2 :(得分:0)

很难从示例中了解您的架构。但是,将strftime强制转换为列表将无法很好地扩展,也不会在模型上循环。而是尝试将employee_ids的列表传递给字段查询queryset

employee_ids = [p[3] for p in periods]
employees = Employees.objects.filter(employee_id__in=employee_ids)

或相反:

employees = Employees.objects.exclude(employee_id__in=employee_ids)