如何在Django中传递`in`SQL子句的值列表

Kry*_*ski 4 database django django-orm

我需要在我正在编写的Django应用程序中使用原始SQL查询.SQL查询inwhere语句中包含一个子句:

select *
from abc_mymodel
where some_fk in (1,2,3)
and some_status = 'foo'
Run Code Online (Sandbox Code Playgroud)

我是将SQL参数作为参数传递的重要支持者.对于单值的数据,这很容易做到.但是,我不确定如何(或是否)可以为in子句做这件事.理想情况下,我想做的事情如下:

sql = """
    select *
    from abc_mymodel
    where some_fk in %s
    and some_status = %s
"""
my_list = [1,2,3]
my_status = 'foo'
trinkets = MyModel.objects.raw(
    sql,
    params=(my_list, my_status)
)
Run Code Online (Sandbox Code Playgroud)

我知道我可以使用字符串组合来编写in子句并使用参数来表示剩余的值.但是,我很好奇是否可以使用params作为in条款.

pco*_*nel 8

根据Django文档raw(),

params是参数列表或字典.您将%s在查询字符串中使用占位符作为列表...这样的占位符将替换为params参数中的参数.

方便的是,原始查询很容易在django shell中测试.如果您只是输入raw()查询,它将RawQuerySet使用您生成的查询打印:

>>> from django.contrib.auth.models import User
>>> pk_list = (1, 3, 6)
>>> User.objects.raw('SELECT * FROM auth_user WHERE id IN %s', params=[pk_list])
<RawQuerySet: 'SELECT * FROM auth_user WHERE id IN (1, 3, 6)'>
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,无论是什么内容params都放在原始查询中.在您的示例中,您需要更改my_list为元组(否则它将看起来像" IN [1,2,3] ")并将params输入更改为列表(params=[my_list, my_status]).

  • 请注意,这不适用于只有一项的元组。字符串输出采用 Python 格式 (34,),SQL 会阻塞该格式。 (3认同)