python - Django,我可以获取包含在查询集中的引用对象吗

标签 python django django-queryset

假设我有这些模型:

模型.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,我可以像这样循环:

for item_due in ItemDue.objects.filter(some_criteria):
    print item_due.item.ref_id

但是,当我进行一些性能测试时,这将返回数据库以获取引用的 Item 对象,因此我必须为每个 ItemDue 运行另一个查询获取 Item.ref_id。这在大型查询中有所不同,因此我想获取 Item.ref_id 以及获取 ItemDue 的查询集。我可以执行 .values('id', 'item__ref_id') 来获取包含 iditem__ref_id 的 ItemDue 的字典。因此,我可以将 .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

请注意循环项目和仅通过所需的时间大约为 .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

从 0.018 秒运行循环到 0.25 秒。如果已经从查询中获取 item.item.ref_id,为什么仅仅处理 item.item.ref_id 就需要 13 倍的时间?

最佳答案

使用select_related在一个查询中获取相关表数据:

for item_due in ItemDue.objects.filter(some_criteria).select_related():
    print item_due.item.ref_id

关于python - Django,我可以获取包含在查询集中的引用对象吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20691871/

相关文章:

python - 如何将 pylab.plot 线放在 pylab.figtext 上?

python - 给定二维列表和值库的所有值的加权平均值

Python:如果测试终止,使 PhantomJS 浏览器关闭

mysql - 如何获取按匹配属性数量排序的查询行?

python - 我可以使用 numpy 来加速这个循环吗?

python - spyder IDE - 使变量资源管理器遵循编辑器的配色方案

django - 多于 1 个外键

python - 批量支付宝

python - 过滤查询集以仅返回每个用户的最佳结果

django - 为什么 django 的 prefetch_related() 只适用于 all() 而不是 filter()?