例如,我有这个模型:
class Person(models.Model):
name = models.CharField(max_length=20)
employer = models.CharField(max_length=20)
class Car(models.Model):
person = models.ForeignKey(Person)
name = models.CharField(max_length=10)
model = models.CharField(max_length=10)
...
好吧,我想让所有人了解自己的具体车型:
people = Person.objects.filter(car__name="Toyota")
现在我想写下这些人的汽车细节。我可以这样做:
for person in people:
...
cars = person.car_set.filter(name="Toyota")
...
但它是下一个数据库。我怎么能避免这个?有没有办法做到这一点更简单?
答案 0 :(得分:3)
首先在车名
时选择汽车和相关人员cars = Car.objects.select_related("person").filter(name="Toyota").order_by("person")
现在你拥有所有名称为丰田的汽车以及该汽车的人,按人数排序。
现在使用python itertools.groupby为每个人分组此列表
from itertools import groupby
for k, g in groupby(cars, lambda x: x.person):
person = k
cars = list(g)
现在在那次迭代中你有了这个人和他的车(名字叫“丰田”)。 您会注意到只发生了一个查询,然后对缓存的信息执行以下操作。
答案 1 :(得分:0)
结帐select_related()
,我之前使用它将许多跨多个模型的小查询转换为一个大型查询:https://docs.djangoproject.com/en/dev/ref/models/querysets/#select-related
它的工作原理是预先填充QuerySet
,因此您对car_set
的访问权限已经存在,不会产生新的查询。
答案 2 :(得分:0)
我不相信无论如何都要避免额外的数据库命中。如果您担心提出太多查询,可以尝试这样的事情:
from collections import defaultdict
cars = Car.objects.filter(**kwargs).selected_related('person')
owners = defaultdict(list)
for car in cars:
owners[car.person].append(car)
这应该只是一个选择所有相关汽车和相关人员数据的查询