Django的反向包含/ icontains(Django reverse to contains/

2019-07-21 19:43发布

在这个问题得到了解决问题的反向LIKE的SQL操作,例如,如果字段名为“彼得·约翰逊”,我们可以通过这样的查询找到它:

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

有没有办法做这样的事情在Django Q对象(我要建一个大的查询,因此,使用原始的SQL查询将不会是理性的)?

Answer 1:

不幸的是,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无关的应用程序为这个特定的任务...



Answer 2:

如果你在的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设置。



Answer 3:

output = MyModel.objects.filter(Q(name__contains="Mr. Peter Johnson"))


文章来源: Django reverse to contains/icontains