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

8
demandé sur christophe31 2011-04-11 14:16:04

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:

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.

7
répondu christophe31 2015-01-18 12:03:23

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!

7
répondu bbrik 2018-06-19 22:06:51

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

1
répondu shadfc 2017-05-23 12:24:31

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

1
répondu djcoin 2012-10-20 07:54:23

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.

0
répondu marianobianchi 2017-10-17 16:43:31