您好我发现在postgres数据库中,我们无法配置默认重音敏感度(在旧邮件交换机上)。
有没有办法让_icontains也对特殊字符(é,è,à,ç,ï)不敏感,或者我必须使用postgres regex用_iregex替换两边(ç-> c,é-> e ...)?
编辑: 这个问题很老,并且在1.8之前为django的用户保留。对于那些使用最新django版本的人来说,这里采用了新的方式:https://docs.djangoproject.com/en/dev/ref/contrib/postgres/lookups/#std:fieldlookup-unaccent
答案 0 :(得分:8)
事实上,在postgres contrib(8.4+)中,有一个非常容易搜索的功能:
for postgres 9 / 8.5:
对于postgres 8.4:
这里是django的用法示例:
vals = MyObject.objects.raw(
"SELECT * \
FROM myapp_myobject \
WHERE unaccent(name) LIKE \'%"+search_text+"%'")
您可以在比较之前对文本搜索应用应用unaccent。
我做的选择是:
#!/usr/bin/env python
# -*- coding: utf-8 -*-
# parts of credits comes to clarisys.fr
from django.db.backends.postgresql_psycopg2.base import *
class DatabaseOperations(DatabaseOperations):
def lookup_cast(self, lookup_type):
if lookup_type in('icontains', 'istartswith'):
return "UPPER(unaccent(%s::text))"
else:
return super(DatabaseOperations, self).lookup_cast(lookup_type)
class DatabaseWrapper(DatabaseWrapper):
def __init__(self, *args, **kwargs):
super(DatabaseWrapper, self).__init__(*args, **kwargs)
self.operators['icontains'] = 'LIKE UPPER(unaccent(%s))'
self.operators['istartswith'] = 'LIKE UPPER(unaccent(%s))'
self.ops = DatabaseOperations(self)
在文件夹中使用此文件base.py
,并将此文件夹用作db后端。 icontains和istartswith现在是案例和重音不敏感。
答案 1 :(得分:7)
我设法从postgresql contrib安装unaccent,但是this answer that patches django没有用。 django.db.utils上的load_backend强制后端名称以django.db.backends开头。
对我有用的解决方案是将此代码插入我的一个模块中:
from django.db.backends.postgresql_psycopg2.base import DatabaseOperations, DatabaseWrapper
def lookup_cast(self, lookup_type, internal_type=None):
if lookup_type in('icontains', 'istartswith'):
return "UPPER(unaccent(%s::text))"
else:
return super(DatabaseOperations, self).lookup_cast(lookup_type, internal_type)
def patch_unaccent():
DatabaseOperations.lookup_cast = lookup_cast
DatabaseWrapper.operators['icontains'] = 'LIKE UPPER(unaccent(%s))'
DatabaseWrapper.operators['istartswith'] = 'LIKE UPPER(unaccent(%s))'
print 'Unaccent patch'
patch_unaccent()
现在,即使在django管理员内部,搜索工作也很好! 谢谢你的回答!
答案 2 :(得分:1)
我不相信你能够使用标准的Django字段查找,除非你将文本的非重音版本存储在另一列中并在那里进行查找。您可以使用editable = False添加重复列,并覆盖模型的save()方法以从原始重音文本更新该字段。
Python:Remove accents from unicode
PostgreSQL Wiki:Strip accents from strings, and output in lowercase
答案 3 :(得分:1)
我刚刚发布了(几天前)django-unaccent库,它将运算符添加到django ORM中以进行非紧密搜索。
它monkeypatch django ORM并使用postgres的unaccent()
函数来执行此操作。
答案 4 :(得分:0)
我正在为django和postgreSQL开发一个非同步的查找字段。它在github上:https://github.com/marianobianchi/django-accent-free-lookup
它现在工作正常,但仍需要大量工作。我正在使用它,它现在没有任何问题。
使用它的方法是为你想要进行不相关搜索的模型创建一个新的Manager(查看存储在项目managers.py文件末尾的示例)。
我已经实现的查找是:
“__ aexact”
“__ aiexact”
“__ acontains”
“__ aicontains”
它们等同于django附带的常见字段查找:
“__精确”
“__ iexact”
“__含”
“__ icontains”
区别在于它们对于最常见的重音字符是“重音不敏感”。