Поиск значения в JSONField с помощью неакцентированных и иконок
У меня есть модель с полем JSONField:
class MyModel(models.Model):
locale_names = models.JSONField()
Форма поля JSON проста: ключи - это коды языков (en, fr...), а значения - переведенные строки.
Я пытаюсь создать поисковый запрос, который выполняет поиск без акцентированных иконок по переведенному значению:
MyModel.objects.filter(locale_names__en__unaccent__icontains="Test")
Это не дает ожидаемых результатов, поскольку Django интерпретирует "unaccent" как ключ для поиска в JSON, а не как функцию unaccent
PostgreSQL:
-- Expected SQL query: something like
SELECT "app_model"."*" ...
FROM "app_model"
WHERE UPPER(UNACCENT("messaging_blueprint"."locale_names" ->>'en')::text)) LIKE UPPER(UNACCENT('%Test%'))
LIMIT 21
-- Actual SQL query
SELECT "app_model"."*" ...
FROM "app_model"
WHERE UPPER(("messaging_blueprint"."locale_names" #>> ARRAY['en','unaccent'])::text) LIKE UPPER('%Test%')
LIMIT 21
Как я могу сказать Django, чтобы он интерпретировал __unaccent
как функцию PostgreSQL, а не как путь JSON?
РЕДАКТИРОВАНИЕ:
- Я использую Django 3.2 .
- Выполнение
__unaccent__icontains
поиска на обычных CharFields работает как ожидалось.
К сожалению, JSONField
не поддерживает unaccent
поиск.
Поиск без акцента можно использовать для CharField и TextField:
В дополнение к ответу @Benbb96 выше, мой обходной путь заключался в том, чтобы написать нужное мне предложение WHERE, используя скоро устаревающий метод QuerySet.extra:
MyModel.objects.extra(
where=[
"UPPER(UNACCENT((app_model.locale_names->>'en')::text)) LIKE UPPER(UNACCENT(%s))"
],
params=("Test",)
)
По просьбе команды Django я создал ticket с ними, чтобы этот случай использования можно было решить без QuerySet.extra()
.