说我有这些模型:
models.py:
class Item(models.Model): ref_id = models.PositiveIntegerField() name = models.CharacterField(max_length=32) class ItemDue(models.Model): item = models.ForeignKey(Item) due_date = models.DateField(null=True, blank=True) lots of other fields below . . .
我想查询ItemDue
对象,但也希望包含Item
查询.
如果我得到一组ItemDue
s,我可以像这样循环:
for item_due in ItemDue.objects.filter(some_criteria): print item_due.item.ref_id
但是,当我进行一些性能测试时,这将返回到数据库以获取引用的Item
对象,因此我必须为每个执行另一个查询ItemDue
来获取Item.ref_id
.这在一个巨大的查询中有所不同,所以我想与查询集Item.ref_id
一起得到ItemDue
s.我可以做.values('id', 'item__ref_id')
一个ItemDue
带id
和的字典item__ref_id
.所以,我可以.values('id', 'item__ref_id', ...)
用于所有领域,ItemDue
但这将是很多工作.有没有一种简单的方法可以附加到查询集的值来获取该引用对象,而不是ItemDue
仅仅添加一个额外的字段来拼写所有字段item__ref_id
?
谢谢
编辑:
以下是在manage.py shell中运行的一些代码:
def check(): start = datetime.now() print "Starting {0}".format(datetime.now() - start) index = 0 item_rows = dict() print "Getting Items for PG and Parents {0}".format(datetime.now() - start) # items due for PG items = pg.item_due.all().filter(disabled=False).select_related() # Loop the parents, and chain their items due to the PG items due. for p in parents: items = itertools.chain(items, p.item_due.all().filter(disabled=False).select_related()) index += 1 print "All Items Retrieved {0}".format(datetime.now() - start) for item in items: pass print "Loop Items Complete {0}".format(datetime.now() - start) return item_rows >>> rows = check() Starting 0:00:00.000008 Getting Items for PG and Parents 0:00:00.000032 All Items Retrieved 0:00:00.004669 Loop Items Complete 0:00:00.022597
注意循环项目所需的时间,pass
大约是0.018秒.
现在我只需pass
将循环更改为item.item.ref_id
并且需要更长的时间.
def check(): start = datetime.now() print "Starting {0}".format(datetime.now() - start) index = 0 item_rows = dict() print "Getting Items for PG and Parents {0}".format(datetime.now() - start) # items due for PG items = pg.item_due.all().filter(disabled=False).select_related() # Loop the parents, and chain their items due to the PG items due. for p in parents: items = itertools.chain(items, p.item_due.all().filter(disabled=False).select_related()) index += 1 print "All Items Retrieved {0}".format(datetime.now() - start) for item in items: item.item.ref_id print "Loop Items Complete {0}".format(datetime.now() - start) return item_rows >>> rows = check() Starting 0:00:00.000007 Getting Items for PG and Parents 0:00:00.000031 All Items Retrieved 0:00:00.004712 Loop Items Complete 0:00:00.258209
从.018秒开始循环到.25秒.为什么只处理item.item.ref_id需要13倍的时间才能从查询中获取它?
使用select_related在一个查询中获取相关表数据:
for item_due in ItemDue.objects.filter(some_criteria).select_related(): print item_due.item.ref_id