我有3个模型,如
class Business(models.Model):
name = models.CharField(max_length=30)
...
class Dude(models.Model):
...
class PhoneNumber(models.Model):
dude = models.ForeignKey(Dude)
date = models.DatetimeField()
business = models.ForeignKey(Business)
我想得到每个家伙的最后3个电话号码,这就是我实现它的方式;
response=list()
for dude in Dude.objects.all():
temp_dude = dict()
temp_dude['name_label'] = str(dude.name)
temp_dude['phones'] = list()
for phone_number in PhoneNumber.objects.filter(dude=dude).order_by("-date")[:3]:
temp_phone = dict()
temp_phone['date_added'] = phone_number.date.timestamp()
temp_phone['business_label'] = str(phone_number.business.name)
temp_dude['phones'].append(temp_phone)
response.append(temp_dude)
但它为每个家伙打了至少两次数据库并消耗了大量的cpu。
使用django orm获得相同响应的最有效方法是什么?
P.S:我有3000万电话号码和170个老兄。答案 0 :(得分:1)
在这种情况下尝试的第一件事是select_related
来获取每个家伙的phone_number。
dudes = Dude.objects.select_related('phone_number', 'phone_number__business').all()
for dude in dudes:
do_the_thing()
(请注意您正在查询的其他对象上的select_related
,phone_number.business
)
在这种情况下,如果每个phone_number
有很多Dude
s,那么这可能会比原始查询更糟糕,因为它会抓取每个Dude.phone_number。
不幸的是,正如评论所暗示的那样,没有ORM方法可以限制select_related
。你需要编写一些SQL。您可以通过调出DB kogging,然后运行自己的custom SQL query来观察SQL Django为select_related查询生成的内容。