Django ORM查询中SQL的“LIKE”等效语句是什么?

171
以下是 SQL 语句在 Django 中的等效语句是什么?
SELECT * FROM table_name WHERE string LIKE pattern;

我尝试了这个:
result = table.objects.filter( pattern in string )

但它没有起作用。我该如何实现它?

7个回答

319
使用__contains__icontains(不区分大小写):
result = table.objects.filter(string__contains='pattern')

SQL的等效语句是
SELECT ... WHERE string LIKE '%pattern%';

@Dmitri的下面的答案涵盖了类似'pattern%'或'%pattern'的模式。

32
为了进行不区分大小写的搜索,请使用 __icontains -> result = table.objects.filter(string__icontains='pattern') - Hitesh Garg
17
此回答仅涵盖可能模式的一个子集。它无法处理像“%a%b%”这样的模式。 - kasperd
1
@kasperd,尝试使用以下代码:result = table.objects.filter(string__contains='a').filter(string__contains='b') - Mr. Lance E Sloan
4
@LS,这将匹配 ba,而 LIKE %a%b% 则不会。 - kasperd
3
这个答案因为之前提到的原因是不完整的。它还应该包括 @Dmitry 的回答中提到的信息。 - medley56
显示剩余4条评论

55

contains与icontains,由falsetru提到,在查询时类似于SELECT ... WHERE headline LIKE '%pattern%'。

除了它们,您可能需要这些具有类似行为的选项:

startswithistartswithendswithiendswith

使得查询变成:

SELECT ... WHERE headline LIKE 'pattern%

或者

SELECT ... WHERE headline LIKE '%pattern


29

这可以通过Django的自定义查询来实现。我已经将该查询转化为一个类Django查询应用程序。安装后,__like查询与%_通配符将被启用。

应用程序中所有必要的代码如下:

from django.db.models import Lookup
from django.db.models.fields import Field


@Field.register_lookup
class Like(Lookup):
    lookup_name = 'like'

    def as_sql(self, compiler, connection):
        lhs, lhs_params = self.process_lhs(compiler, connection)
        rhs, rhs_params = self.process_rhs(compiler, connection)
        params = lhs_params + rhs_params
        return '%s LIKE %s' % (lhs, rhs), params

1
这是正确的答案,不像被接受的答案。 - Lutz Prechelt
1
这很酷,但用户是否存在将脏数据传递到查询中的风险? - wihlke
这是正确的答案。有了这个答案,我永远不会再添加中间的百分号了。 - juan Isaza

9
result = table.objects.filter(string__icontains='pattern')

在字段中进行不区分大小写的字符串搜索。


10
好的,但是几乎三年前就已经给出了相同的答案。 - Mr. Lance E Sloan

4
为了保留与 SQL LIKE '%pattern%' 语句中单词顺序一致,我使用 iregex。例如:
qs = table.objects.filter(string__iregex=pattern.replace(' ', '.*'))

字符串方法是不可变的,所以您的模式变量不会改变,并且使用 .* 您将寻找任何字符但不包括换行符的 0 或多个出现。

通过使用以下内容迭代模式单词:

qs = table.objects
for word in pattern.split(' '):
    qs = qs.filter(string__icontains=word)

您的模式中单词的顺序将不被保留,对于某些人来说可能有效,但在尝试模仿SQL like语句的情况下,我将使用第一种选项。


你可能想将替换项. *?作为懒惰匹配,而不是消耗整个字符串。 - wihlke

3

完整示例:假设我们有一个名为DjangTable的表,其中包含字符串字段name file_name,并且我们想要创建Django过滤器,其相当于在mysql中匹配file_name字符串中的空格的查询:

SELECT * FROM DjangTable WHERE file_name LIKE '% %' 
class DjangTable(UTModel):


    ...
    file_name = models.CharField(max_length=255, null=False)
    ...

在使用Python的Django中,它将是这样的:

pattern = ' ' # same as mysql LIKE '% %'
DjangTable.objects.filter(file_name__contains=pattern)

0

Django ORM查询中的SQL "LIKE"等效:

SQL查询:

SELECT * or any_column_name 
FROM table_name
WHERE string LIKE '%pattern%';

等效的Django ORM查询模式:
qs = Model.objects.filter(column_name__contains='string_pattern')

等效的Django ORM查询示例:如果模型是:Book,列是:id,name等,则ORM查询将如下所示:
qs = Book.objects.filter(name__contains='programming')

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接