Django反转为包含/图标

在这个问题中解决了SQL中反向LIKE操作的问题,例如,如果字段名称是“Peter Johnson”,我们可以通过以下查询找到它:

select name from user where "Mr. Peter Johnson" like CONCAT('%', name, '%')

有没有什么办法在Django Q对象中做这样的事情(我正在构建一个大的查询,所以使用原始SQL查询将不合理)?


不幸的是,Django的ORM没有内置反向LIKE的内容。 但.extra()子句可能会使其比原始查询更容易一些。

我用了这样的东西:

qs.extra(
    where=['''%s LIKE %s.%s'''],
    params=(
        "string to match",
        FooModel._meta.db_table,
        "bar_field",
    ),
)

上面的代码的问题是

1)它不适用于这种形式的sqlite后端(“附近的语法错误”,它可以在查询中硬编码的表/列名称工作...这并不总是安全和总是丑陋的);

2)它需要FooModel.bar_field将数据%in like style%因此您无法匹配任意字符串(这可以通过%s LIKE CONCAT("%", %s.%s, "%")但它会使它成为DBMS特有的,这是不好的)。

反转的LIKE本身可能适用于任何主要的DBMS,但我只在sqlite和postgres上测试过它。

也许有人应该概括我的解决方案,并为此特定任务创建一个可重用的,DBMS不可知的应用程序,其中包含特殊的子集化查询集/管理器/ Q对象。


如果您使用的是最新版本的Django(1.10或更高版本)并使用Postgres,则ORM可以处理此问题。 查看文档。

trigram_similar查找会为您提供您正在寻找的内容:

qs = MyModel.objects.filter(name__trigram_similar='Mr. Peter Johnson')

不要忘记通过启用pg_tgrm扩展来启用此查找。 你可以用django迁移来做到这一点。

您需要将'django.contrib.postgres'添加到您的INSTALLED_APPS设置中。


output = MyModel.objects.filter(Q(name__contains="Mr. Peter Johnson"))
链接地址: http://www.djcxy.com/p/6591.html

上一篇: Django reverse to contains/icontains

下一篇: word match only in Django query