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