Django,我可以获得查询集中包含的引用对象

 yuanguo374 发布于 2023-02-09 09:43

说我有这些模型:

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查询.

如果我得到一组ItemDues,我可以像这样循环:

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

但是,当我进行一些性能测试时,这将返回到数据库以获取引用的Item对象,因此我必须为每个执行另一个查询ItemDue来获取Item.ref_id.这在一个巨大的查询中有所不同,所以我想与查询集Item.ref_id一起得到ItemDues.我可以做.values('id', 'item__ref_id')一个ItemDueid和的字典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倍的时间才能从查询中获取它?

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

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

    2023-02-09 09:49 回答
撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有