【问题标题】:Combine model data with list of objects将模型数据与对象列表相结合
【发布时间】:2010-11-21 06:54:02
【问题描述】:

我有一个对象列表:

film_hc = [{'count': 2, 'pk': '33'},
           {'count': 1, 'pk': '37'},
           {'count': 1, 'pk': '49'}]

“pk”值是模型中记录的主键。我想将该记录的名称字段添加到此对象列表中。要获得一个名字,我可以使用:

record = Film.objects.get(pk = film_hc[0]['pk'])  
record.name

最后,我想要这样的东西:

film_hc = [{'count': 2, 'pk': '33', 'name': 'name1'},
           {'count': 1, 'pk': '37', 'name': 'name2'},
           {'count': 1, 'pk': '49', 'name': 'name3'}]

问题:将必要数据附加到这个预先存在的列表中最有效的方法是什么?

我想我可以使用 zip 功能:

film_hc_with_names = zip(????, film_hc)

问题是我不确定我会用什么来代替那些????获取对象,然后是列表中每个对象的名称。我应该改用 for 循环吗?最好的选择是什么?

【问题讨论】:

    标签: python django zip


    【解决方案1】:

    为避免多次访问数据库,我建议您使用in_bulk queryset 方法。这需要一个 ID 列表,并返回映射到模型实例的 ID 字典。因此,您需要做的是首先运行您的字典列表以提取 ID 值,然后进行查询,然后再次运行以获取每个实例的名称。即使这会进行两次额外的迭代,它仍然应该比运行多个数据库查询更快(尽管您应该像往常一样进行分析以确保)。

    id_list = [film['id'] for film in film_hc]
    objects = Film.objects.only('name').in_bulk(id_list)
    for film in film_hc:
        film['name'] = objects[film['id']].name
    

    【讨论】:

    • 我一定会在某个时候找到 in_bulk 的用途。在这种情况下,我不知道迭代两次是否有意义。看来我们可以一次性完成。
    • @Ed 这当然取决于你,但你不应该只关注迭代是主要的低效率。多次单独访问数据库效率要低得多。对我的代码和上面的 aaronsterling 的代码运行 ab 进行 100 次点击的快速测试显示,我的代码为 0.370 毫秒,而他的代码为 0.542 毫秒:所以我的方法效率大约提高了 50%。
    • 嗯。你是对的。测试它,这确实工作得更快。感谢您的跟进。
    猜你喜欢
    • 2018-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-12
    • 2021-03-09
    • 2014-09-11
    • 1970-01-01
    相关资源
    最近更新 更多