解决了this中反向LIKE
操作的问题,例如字段名为"Peter Johnson",我们可以通过这样的查询找到它:
select name from user where "Mr. Peter Johnson" like CONCAT('%', name, '%')
有没有办法在Django Q
object中做这样的事情(我正在构建一个大查询,所以使用原始的SQL查询将是不合理的)?
发布于 2019-07-18 23:44:05
虽然extras确实为边缘情况提供了扩展的复杂功能,但extras应该被视为最后的手段,并可能在某些时候被弃用。
这可以使用注解和过滤来完成。
from django.db.models import F, Value, CharField
MyUserModel.objects \
.annotate(my_name_field=Value('Mr. Peter Johnson', output_field=CharField())) \
.filter(my_name_field__icontains=F('name'))
泛化为:
from django.db.models import F, Value, CharField
@staticmethod
def reverse_case_insensitive_contains(model, search_field_name: str, search_field_value: str):
return model.objects \
.annotate(search_field=Value(search_field_value, output_field=CharField())) \
.filter(search_field__icontains=F(search_field_name))
发布于 2014-10-28 04:38:44
不幸的是,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,这不太好)。
反向转换本身可能适用于任何主要的DBMS,但我只在sqlite和postgres上测试了它。
也许有人应该推广我的解决方案,为这个特定的任务创建一个可重用的、与DBMS无关的应用程序,它具有特殊的子类queryset/manager/Q-object……
发布于 2017-06-22 01:00:11
如果您使用的是最新版本的Django (1.10或更高版本)并使用Postgres,则ORM可以处理此问题。Check out the docs.
trigram_similar
查找将得到您正在查找的内容:
qs = MyModel.objects.filter(name__trigram_similar='Mr. Peter Johnson')
不要忘记通过启用pg_tgrm扩展来启用此查找。您可以使用django migration来完成此操作。
你还需要在你的INSTALLED_APPS
设置中添加'django.contrib.postgres'
。
https://stackoverflow.com/questions/15465858
复制相似问题