comment avoir filtre insensible à L'Accent en django avec postgres?
Salut je trouve que sur la base de données postgres, on ne peut pas configurer la sensibilité d'accent par défaut (sur les anciens échanges de courrier).
y a-t-il un moyen d'avoir un _icontains aussi insensible aux caractères spéciaux (é, è, à, ç, ï) ou je dois utiliser postgres regex pour remplacer les deux côtés par _iregex (ç - >c, é - >E...)?
modifier: cette question Est ancienne, et est conservée pour les utilisateurs de django Avant 1.8. Pour ceux qui utilisent les dernières versions de django, voici la nouvelle façon: https://docs.djangoproject.com/en/dev/ref/contrib/postgres/lookups/#std:fieldlookup-unaccent
5 réponses
EDIT: Django 1.8 rend l'accent unsensitive lookup pour postgresql builtin. https://docs.djangoproject.com/en/dev/ref/contrib/postgres/lookups/#std:fieldlookup-unaccent
en fait, Dans postgres contrib (8.4+) il y a un unaccent fonction pour rechercher facilement:
pour postgres 9/8.5:
- https://github.com/adunstan/postgresql-dev/commits/master/contrib/unaccent
- http://www.sai.msu.su / ~ megera / wiki/uncent
pour postgresql 8.4.:
voici un exemple d'utilisation de django:
vals = MyObject.objects.raw(
"SELECT * \
FROM myapp_myobject \
WHERE unaccent(name) LIKE \'%"+search_text+"%'")
vous pouvez appliquer appliquer sans objet sur la recherche textuelle avant comparaison.
L'Option que j'ai faite est:
#!/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)
utilisez ce fichier base.py
dans un dossier et utilisez ce dossier comme backend de db. icontains et istartswith sont maintenant insensibles à la casse et à l'accent.
j'ai réussi à installer unaccent de postgresql contrib, mais ça n'a pas marché. load_backend sur django.DB.utils fait respecter que le nom d'arrière-plan commence par django.DB.backends.
la solution qui a fonctionné pour moi était d'insérer ce code dans un de mes modules:
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()
les recherches non effectuées fonctionnent bien, même à l'intérieur de django admin! Merci pour votre réponse ci-dessus!
Je ne crois pas que vous serez en mesure d'utiliser le standard Django field-lookup pour cela à moins que vous ne stockez une version non accentuée de votre texte dans une autre colonne et faire la recherche là-bas. Vous pouvez ajouter une colonne dupliquée avec editable=False et outrepasser la méthode save() du model pour mettre à jour ce champ à partir du texte accentué original.
Python: Supprimer les accents d'unicode
PostgreSQL Wiki: enlever les accents des cordes, et la sortie dans minuscules
je viens de sortir (il y a quelques jours) la bibliothèque django-uncentent qui ajoute des opérateurs à l'ORM de django pour la recherche d'uncent.
Il monkeypatch l'ORM django et utilise le unaccent()
fonction de postgres pour le faire.
s'il vous Plaît, vérifiez => https://github.com/djcoin/django-unaccent
je travaille sur un champ de recherche non identifié pour django et postgreSQL. C'est sur github: https://github.com/marianobianchi/django-accent-free-lookup
ça marche bien pour l'instant, mais ça a encore besoin de beaucoup de travail. Je l'utilise et il ne montre aucun problème pour le moment.
La façon de l'utiliser est de faire un nouveau Gestionnaire pour le modèle que vous désirez avoir unaccents recherches (regardez l'exemple stockée à la fin de managers.py le fichier à l' projet.)
les recherches que j'ai déjà implémentées sont:
"_ _ aexact"
"_ _ aiexact"
"_ _ _ acontains"
"_ _ aicontains"
ils sont équivalents aux Lookup communs de terrain qui viennent avec django:
"__exacte"
"_ _ _ iexact"
"__contient"
"__icontains"
avec la différence qu'ils sont "insensible aux accents" pour la plupart des caractères accentués.