【问题标题】:Most efficient way to use the django ORM when comparing elements from two lists比较两个列表中的元素时使用 django ORM 的最有效方法
【发布时间】:2012-10-01 22:25:27
【问题描述】:
model_one_list = Model1.objects.all()
model_two_list = Model2.objects.filter(...).order_by(..)

for model in model_one_list:
    for model2 in model_two_list:
        if model.field == model2.field:
            another_list.append(model)

一些针对 django ORM 的在线提示特别提到不要这样做,因为它使用太多内存并损害性能,文档建议尽可能坚持使用 ORM。

我试图用这个来解决上面的问题:

Model1.objects.extra(
    where={
        'field = app_model2.field' 
        # Not sure if this works, I think the app_model2 may be wrong idk if i
        # can access that
    },
)

但是对于这样的事情,我不太确定如何处理。

还有一个有点相关的最后一个问题。 如果我有一个查询集需要简单地按排序计数进行排序,那是什么 推荐的无需迭代​​的方法?

Model1.objects.order_by('something').extra(select={'rank':
"how do i get the rank in mysql??? like while its
 iterating, is this even possible"})

感谢您的帮助。

【问题讨论】:

    标签: python django orm


    【解决方案1】:

    第一个问题:加入不相关的模型

    我假设你的Model1Model2 不相关,否则你可以使用Django's related objects 接口。您可以采取以下两种方法:

    1. 使用 extra 和 SQL 子查询:

      Model1.objects.extra(where = ['field in (SELECT field from myapp_model2 WHERE ...)'])
      

      在某些数据库(尤其是 MySQL)中,子查询的处理效率不高,因此这可能不如下面的 #2。

    2. 使用raw SQL query

      Model1.objects.raw('''SELECT * from myapp_model1
                         INNER JOIN myapp_model2
                         ON myapp_model1.field = myapp_model2.field
                         AND ...''')
      

    第二个问题:枚举结果

    两种方法:

    1. 您可以在 Python 中使用内置的enumerate 函数枚举查询集:

      enumerate(Model1.objects.all())
      
    2. 您可以使用this answer 中描述的技术在 MySQL 中进行枚举。像这样的:

      Model1.objects.raw('''SELECT *, @row := @row + 1 AS row
                         FROM myapp_model1
                         JOIN (SELECT @row := 0) rowtable
                         INNER JOIN myapp_model2
                         ON myapp_model1.field = myapp_model2.field
                         AND ...''')
      

    【讨论】:

    • 假设显示在有序列表中的条目列表,id 就像每个条目都有一个基于该排序的排名,这纯粹是为了在模板中显示。如条目 1、条目 2、...等
    • 谢谢,好久没有这么详细的答案了!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-18
    • 2016-05-17
    • 2019-12-07
    • 2012-07-23
    相关资源
    最近更新 更多