在这个问题得到了解决问题的反向LIKE
的SQL操作,例如,如果字段名为“彼得·约翰逊”,我们可以通过这样的查询找到它:
select name from user where "Mr. Peter Johnson" like CONCAT('%', name, '%')
有没有办法做这样的事情在Django Q
对象(我要建一个大的查询,因此,使用原始的SQL查询将不会是理性的)?
在这个问题得到了解决问题的反向LIKE
的SQL操作,例如,如果字段名为“彼得·约翰逊”,我们可以通过这样的查询找到它:
select name from user where "Mr. Peter Johnson" like CONCAT('%', name, '%')
有没有办法做这样的事情在Django Q
对象(我要建一个大的查询,因此,使用原始的SQL查询将不会是理性的)?
不幸的是,Django的ORM没有任何内置的反向喜欢。 但是,一个.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本身或许应该与任何主要的数据库管理系统的工作,但我测试了它只能在SQLite和Postgres的。
也许有人要概括我的解决方案,并创建具有特殊子类的查询集/经理/ Q-对象可重复使用,DBMS无关的应用程序为这个特定的任务...
如果你在的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"))