【问题标题】:sql "LIKE" equivalent in django querydjango查询中的sql“LIKE”等价物
【发布时间】:2013-08-11 00:58:02
【问题描述】:

django 中这条 SQL 语句的等价物是什么?

SELECT * FROM table_name WHERE string LIKE pattern;

如何在 django 中实现这一点?我试过了

result = table.objects.filter( pattern in string )

但这没有用。我该如何实施?

【问题讨论】:

    标签: python sql django django-models django-queryset


    【解决方案1】:

    使用__contains__icontains(不区分大小写):

    result = table.objects.filter(string__contains='pattern')
    

    SQL 等价物是

    SELECT ... WHERE string LIKE '%pattern%';
    

    【讨论】:

    • 对于不区分大小写的搜索,请使用 __icontains -> result = table.objects.filter(string__icontains='pattern')
    • 此答案仅涵盖可能模式的子集。它不会处理像%a%b% 这样的模式。
    • @kasperd,试试:result = table.objects.filter(string__contains='a').filter(string__contains='b')
    • @LS 匹配 baLIKE %a%b% 不匹配。
    • 由于上述原因,此答案不完整。它还应该包含@Dmitry 的答案中的信息。
    【解决方案2】:

    falsetru 提到的contains 和icontains 进行SELECT ... WHERE headline LIKE '%pattern% 之类的查询

    除了它们之外,您可能还需要具有类似行为的这些: startswithistartswithendswithiendswith

    制作

    SELECT ... WHERE headline LIKE 'pattern%

    SELECT ... WHERE headline LIKE '%pattern

    【讨论】:

      【解决方案3】:

      这可以通过Django's custom lookups 完成。我已将查找设为Django-like-lookup application。安装后,将启用带有 %_ 通配符的 __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
      

      【讨论】:

      • 这是问题的正确答案,与接受的答案不同。
      【解决方案4】:
      result = table.objects.filter(string__icontains='pattern')
      

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

      【讨论】:

      • 很好,但差不多三年前已经给出了相同的答案。
      【解决方案5】:

      为了保持 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 语句的情况下,我将使用第一个选项。

      【讨论】:

        【解决方案6】:

        完整示例:假设我们有一个名为 DjangTable 的表,其中包含字符串字段名称 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)
            ...
        

        在 Django 中使用 python 它将是:

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

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2013-04-14
          • 2021-08-24
          • 2012-02-18
          • 2019-11-14
          • 1970-01-01
          • 1970-01-01
          • 2012-10-29
          相关资源
          最近更新 更多