diff --git a/zoo/zoo_data/lookups.py b/zoo/zoo_data/lookups.py index 7693de3..cf01358 100644 --- a/zoo/zoo_data/lookups.py +++ b/zoo/zoo_data/lookups.py @@ -16,87 +16,40 @@ import django -from django.db.models import Transform, TextField, DateField +from django.db.models import Transform, CharField, DateField +from django.db.models.functions import Lower from django.contrib.postgres.fields import jsonb try: - from django.contrib.postgres.fields.jsonb import KeyTransform, KeyTransformTextLookupMixin + from django.db.models.fields.json import KeyTransform, KeyTransformTextLookupMixin except ImportError: - # backport from Django 2.x - class KeyTransform(Transform): - operator = '->' - nested_operator = '#>' - - def __init__(self, key_name, *args, **kwargs): - super(KeyTransform, self).__init__(*args, **kwargs) - self.key_name = key_name - - def as_sql(self, compiler, connection): - key_transforms = [self.key_name] - previous = self.lhs - while isinstance(previous, KeyTransform): - key_transforms.insert(0, previous.key_name) - previous = previous.lhs - lhs, params = compiler.compile(previous) - if len(key_transforms) > 1: - return "(%s %s %%s)" % (lhs, self.nested_operator), [key_transforms] + params - try: - int(self.key_name) - except ValueError: - lookup = "'%s'" % self.key_name - else: - lookup = "%s" % self.key_name - return "(%s %s %s)" % (lhs, self.operator, lookup), params - - jsonb.KeyTransform = KeyTransform - - class KeyTextTransform(KeyTransform): - operator = '->>' - nested_operator = '#>>' - _output_field = TextField() - - class KeyTransformTextLookupMixin(object): - """ - Mixin for combining with a lookup expecting a text lhs from a JSONField - key lookup. Make use of the ->> operator instead of casting key values to - text and performing the lookup on the resulting representation. - """ - def __init__(self, key_transform, *args, **kwargs): - assert isinstance(key_transform, KeyTransform) - key_text_transform = KeyTextTransform( - key_transform.key_name, *key_transform.source_expressions, **key_transform.extra - ) - super(KeyTransformTextLookupMixin, self).__init__(key_text_transform, *args, **kwargs) - - -class Lower(Transform): - lookup_name = 'lower' - function = 'LOWER' - -TextField.register_lookup(Lower) + from django.contrib.postgres.fields.jsonb import KeyTransform, KeyTransformTextLookupMixin class Unaccent(Transform): lookup_name = 'unaccent' function = 'immutable_unaccent' + output_field = CharField() -TextField.register_lookup(Unaccent) +CharField.register_lookup(Unaccent) +CharField.register_lookup(Lower) class Normalize(Transform): lookup_name = 'normalize' function = 'immutable_normalize' + output_field = CharField() -TextField.register_lookup(Normalize) +CharField.register_lookup(Normalize) class Date(Transform): lookup_name = 'timestamp' function = 'immutable_date' - _output_field = DateField() + output_field = DateField() -TextField.register_lookup(Date) +CharField.register_lookup(Date) class JSONUnaccent(KeyTransformTextLookupMixin, Unaccent): diff --git a/zoo/zoo_data/models.py b/zoo/zoo_data/models.py index 2c02446..cf4c58a 100644 --- a/zoo/zoo_data/models.py +++ b/zoo/zoo_data/models.py @@ -24,6 +24,7 @@ import datetime from django.db import models, connection from django.db.models import F, Value +from django.db.models.functions import Lower from django.db.models.query import QuerySet, Q from django.core.exceptions import ValidationError from django.urls import reverse @@ -33,7 +34,7 @@ from django.contrib.postgres.fields import JSONField from django.contrib.postgres.search import TrigramDistance -from .search import Unaccent, Lower, JSONTextRef +from .search import Unaccent, JSONTextRef from zoo.zoo_meta.validators import schema_validator @@ -74,7 +75,7 @@ class EntityQuerySet(QuerySet): for key, value in kwargs.items(): filters.append(Q(**{ 'content__' + key + '__unaccent__lower__trigram_similar': - Lower(Unaccent(Value(value))), + Unaccent(Lower(Value(value))), })) qs = qs.filter(functools.reduce(__or__, filters)) expressions = [] diff --git a/zoo/zoo_data/search.py b/zoo/zoo_data/search.py index c7dc555..f5ee6a1 100644 --- a/zoo/zoo_data/search.py +++ b/zoo/zoo_data/search.py @@ -14,7 +14,7 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . -from django.db.models import Func, Value +from django.db.models import Func, Value, CharField class Unaccent(Func): @@ -27,11 +27,6 @@ class Normalize(Func): arity = 1 -class Lower(Func): - function = 'LOWER' - arity = 1 - - class JSONRef(Func): function = '' arg_joiner = '->' @@ -46,6 +41,7 @@ class JSONTextRef(Func): function = '' arg_joiner = '->>' arity = 2 + output_field = CharField() def __init__(self, *expressions, **extra): jsonb = expressions[0] diff --git a/zoo/zoo_nanterre/utils.py b/zoo/zoo_nanterre/utils.py index a0d338a..35405ed 100644 --- a/zoo/zoo_nanterre/utils.py +++ b/zoo/zoo_nanterre/utils.py @@ -38,7 +38,7 @@ import psycopg2 from django.conf import settings from django.contrib.postgres.search import TrigramDistance from django.db import connection -from django.db.models import Q, F, Value, ExpressionWrapper, CharField, When, Case +from django.db.models import Q, F, Value, ExpressionWrapper, CharField, When, Case, CharField from django.db.models.functions import Least, Greatest, Coalesce, Concat from django.db import transaction from django.contrib.auth.hashers import make_password @@ -541,7 +541,7 @@ class PersonSearch(object): Coalesce( JSONTextRef(F('content'), 'nom_d_usage'), JSONTextRef(F('content'), 'nom_de_naissance'), - Value(' ') + Value(' '), ), Value(' '), JSONTextRef(F('content'), 'prenoms'))