【问题标题】:Django charfield queryset filter without escaping the MYSQL wildcard没有转义 MYSQL 通配符的 Django charfield 查询集过滤器
【发布时间】:2011-12-29 06:05:39
【问题描述】:

我正在寻找一种方法来做到这一点:

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 次随机查询使用 regex 方法耗时 20.5 秒,使用这种方法 2000 次随机查询耗时 6 秒。

【问题讨论】:

    标签: python django django-models


    【解决方案1】:

    我什至不知道 django 有这个 __like 版本。好吧,但是根据文档,请阅读此内容! https://docs.djangoproject.com/en/dev/topics/db/queries/#escaping-percent-signs-and-underscores-in-like-statements

    您应该这样编写查询。

        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

    【讨论】:

    • 啊,抱歉,我不清楚。我想得到类似原始的 Like 的东西。 __contains 将为我们避开下划线。这是一个很棒的安全功能,但我希望能够将其关闭。
    • 发现这个stackoverflow.com/questions/2317452/django-count-rawqueryset 你可以通过执行 len(list(rawQS)) 来获得长度。但有任何性能改进
    • 为此,您可以使用提供的额外方法。 Entry.objects.extra(where="mystring LIKE '____10____'")
    • 您的第二个答案中有几个拼写错误导致格式崩溃,而该方法有效。它应该是:where=["'mystring' LIKE '____10____'"] 除了 mystring 周围的引号应该是 `
    • 你能编辑一下这个问题,以便我投票吗?当我想接受时,我无意中点击了反对票,而我的投票目前已被锁定。
    【解决方案2】:

    您可以使用 raw() 管理器执行原始 SQL 查询,因此该行将变为:

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

    【讨论】:

    • 它绝对是一个选项,但我从不喜欢原始查询集。除非他们有我不知道的属性,否则无法判断他们是否有数据,他们的长度,或者你是否有错误
    【解决方案3】:

    我建议regex filter function 或不区分大小写的iregex version。示例:

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

    缺点:您可以检查您使用的后端的正则表达式支持,对性能的影响,并且在后端更改的情况下,这可能会导致潜在问题:正则表达式语法是正在使用的数据库后端的语法.

    【讨论】:

      猜你喜欢
      • 2014-06-14
      • 2018-09-29
      • 2010-10-14
      • 2016-09-11
      • 2019-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-12
      相关资源
      最近更新 更多