【问题标题】:Django - how can I do this query in the ORMDjango - 我如何在 ORM 中执行此查询
【发布时间】:2018-12-05 07:29:34
【问题描述】:

大家好,我正在尝试进行此查询:

SELECT * 
FROM dashboard_informe inf
INNER JOIN dashboard_servicio serv ON inf.servicio_id = serv.id
WHERE serv.nombre LIKE 'Inventario' AND inf.nombre LIKE 'Inventario%'

我不知道怎么做,我试过这个:

b = Servicio.objects.all().values_list('id')
r = Informe.objects.filter(servicio_id=b)

它给了我一个错误:'精确查找的 QuerySet 值必须限制为' ValueError:精确查找的 QuerySet 值必须使用切片限制为一个结果。

有办法做到这一点吗?或者更好地使用该查询创建一个存储过程?

转发谢谢!

【问题讨论】:

    标签: python django django-orm


    【解决方案1】:

    我想你正在寻找__in field lookup

    b = Servicio.objects.filter(nombre__startswith='Inventario').values('id')
    r = Informe.objects.filter(servicio_id__in=b)
    

    Django 会将第一个查询转换为子查询,从而使 SQL 看起来像这样:

    SELECT ... 
    FROM dashboard_informe inf 
    WHERE inf.id IN (
        SELECT s.id 
        FROM dashboard_servicio s 
        WHERE s.nombre LIKE 'Inventario%'
    );
    

    【讨论】:

      【解决方案2】:
      SELECT * 
      FROM dashboard_informe inf
      INNER JOIN dashboard_servicio serv ON inf.servicio_id = serv.id
      WHERE serv.nombre LIKE 'Inventario' AND inf.nombre LIKE 'Inventario%'
      
      r = Informe.objects.filter(servicio__nombre='Inventario', nombre__startswith='Inventario')
      

      【讨论】:

        【解决方案3】:

        最好使用values_list()

        b = Servicio.objects.all().values_list('id', flat=True) r = Informe.objects.filter(servicio_id__in=b)

        【讨论】:

        • 你能解释为什么values_list更好吗?
        • 是的,在python中使用b的结果可能会有一点性能提升,但在这种情况下,django将其转换为子查询,使用完全相同的sql。类似于SELECT ... FROM dashboard_informe inf WHERE inf.id IN (SELECT s.id FROM dashboard_servicio s WHERE s.nombre LIKE 'Inventario%';
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-06-26
        • 1970-01-01
        • 2010-10-26
        • 2013-12-13
        • 1970-01-01
        • 1970-01-01
        • 2021-03-08
        相关资源
        最近更新 更多