Django CharField 查询集过滤不转义 MYSQL 通配符

2 投票
3 回答
3135 浏览
提问于 2025-04-17 09:11

我想找到一种方法来做到这个:

qs = MyModel.objects.filter(mystring__like="____10____")

#Which would create a sql clause
... LIKE '____10____'

而不是像这样表现:

qs = MyModel.objects.filter(mystring__icontains="____10____")
#Which creates a sql clause
... LIKE %\_\\_\\_\\_10\\_\\_\\_\\_%

我知道可以用正则表达式过滤,但这样做会慢很多,而且更容易出错。相比之下,直接使用mysql自带的通配符功能要简单得多(我在mysql里直接测试过,查询字符串很长,所以两者的速度差别很明显)。


补充说明:在madisvain的帮助下,我找到了用.extra()方法实现这个功能的方法。

qs = MyModel.objects.extra(where=["`mystring` LIKE '____10____'"])

在性能方面,使用正则表达式的方法执行2000个随机查询花了20.5秒,而用这种方法执行2000个随机查询只需6秒。

3 个回答

0

我建议你使用正则表达式过滤功能,或者不区分大小写的不区分大小写的正则表达式版本。举个例子:

qs = MyModel.objects.filter(mystring__regex="....10....")

缺点是:你需要检查一下你使用的后端是否支持正则表达式,这可能会影响性能。而且如果你更换后端,这可能会导致一些潜在的问题:正则表达式的语法是根据你使用的数据库后端来决定的

1

你可以使用 raw() 管理器来执行原始的 SQL 查询,所以这行代码可以改成:

qs = MyModel.objects.raw("SELECT * from MyApp_MyModel where mystring like %s", [variable])
1

我之前都不知道Django有这个__like的版本。不过根据文档,请你看看这个!

你应该这样写查询。

    qs = MyModel.objects.filter(mystring__contains="____10____")

或者这样。

    qs = MyModel.objects.extra(where="mystring LIKE '____10____'")

想了解更多关于extra()方法的内容,可以在这里查看:

https://docs.djangoproject.com/en/dev/ref/models/querysets/#extra

撰写回答