как сделать нечувствительный к акценту фильтр в django с postgres? - PullRequest
8 голосов
/ 11 апреля 2011

Привет, я обнаружил, что в базе данных postgres мы не можем настроить чувствительность по умолчанию к акценту (на старых почтовых обменах).

Есть ли способ сделать _icontains нечувствительным к специальным символам (é, è,à, ç, ï) или я должен использовать регулярное выражение postgres, чтобы заменить обе стороны на _iregex (ç-> c, é-> e ...)?

edit: этот вопрос старый и хранится дляпользователи django до 1.8.Для тех, кто использует последние версии Django, здесь новый способ: https://docs.djangoproject.com/en/dev/ref/contrib/postgres/lookups/#std:fieldlookup-unaccent

Ответы [ 5 ]

8 голосов
/ 26 апреля 2011

РЕДАКТИРОВАТЬ: Django 1.8 делает нечувствительным к акценту поиск для postgresql. https://docs.djangoproject.com/en/dev/ref/contrib/postgres/lookups/#std:fieldlookup-unaccent

На самом деле в postgres contrib (8.4+) есть функция unaccent для удобного поиска:

для 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 теперь нечувствительны к регистру и акценту.

7 голосов
/ 15 сентября 2011

Мне удалось установить unaccent из postgresql contrib, но этот ответ о том, что патчи django не сработали.load_backend на django.db.utils обеспечивает, чтобы имя бэкенда начиналось с 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 admin!Спасибо за ваш ответ выше!

1 голос
/ 31 мая 2012

Я только что выпустил (несколько дней назад) библиотеку django-unaccent, которая добавляет операторы в ORM django для поиска без акцента. Он устанавливает патч для django ORM и использует для этого функцию unaccent() postgres.

Пожалуйста, проверьте это => https://github.com/djcoin/django-unaccent

1 голос
/ 11 апреля 2011

Я не верю, что вы сможете использовать для этого стандартные полевые поиски Django, если вы не сохраните не акцентированную версию вашего текста в другом столбце и не выполните поиск там. Вы можете добавить дубликат столбца с editable = False и переопределить метод save () модели, чтобы обновить это поле из исходного акцентированного текста.

Python: Удалить акценты из Unicode

PostgreSQL Wiki: Удаление акцентов из строк и вывод в нижнем регистре

0 голосов
/ 22 мая 2012

Я работаю над неактивным полем поиска для django и postgreSQL.Он на github: https://github.com/marianobianchi/django-accent-free-lookup

Пока он работает нормально, но все еще требует много работы.Я использую это, и это пока не показывает никаких проблем.

Способ его использования - создать новый менеджер для модели, в которой вы хотите выполнять поиск без акцента (посмотрите на пример, хранящийся в конце файла Manager.py проекта)..

Поиск, который я уже реализовал:

"__ aexact"

"__ aiexact"

"__ acontains"

"__aicontains"

Они эквивалентны обычным полевым поискам, которые поставляются с django:

"__ точных"

"__ iexact"

"__ содержит"

"__ icontains"

с той разницей, что они "нечувствительны к акценту" для наиболее распространенных акцентированных символов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...