From 5c24c16e68868b33ea0bb30173403da51a078d2e Mon Sep 17 00:00:00 2001 From: Mariusz Felisiak Date: Wed, 1 Apr 2020 10:55:53 +0200 Subject: [PATCH] Refs #12990 -- Moved PostgresSimpleLookup to the django.db.models.lookups.PostgresOperatorLookup. --- django/contrib/postgres/fields/ranges.py | 33 ++++++++++---------- django/contrib/postgres/lookups.py | 38 ++++++++++-------------- django/db/models/lookups.py | 11 +++++++ 3 files changed, 43 insertions(+), 39 deletions(-) diff --git a/django/contrib/postgres/fields/ranges.py b/django/contrib/postgres/fields/ranges.py index 9a89fda02d..c2f24eb5ed 100644 --- a/django/contrib/postgres/fields/ranges.py +++ b/django/contrib/postgres/fields/ranges.py @@ -5,6 +5,7 @@ from psycopg2.extras import DateRange, DateTimeTZRange, NumericRange, Range from django.contrib.postgres import forms, lookups from django.db import models +from django.db.models.lookups import PostgresOperatorLookup from .utils import AttributeSetter @@ -161,13 +162,13 @@ RangeField.register_lookup(lookups.ContainedBy) RangeField.register_lookup(lookups.Overlap) -class DateTimeRangeContains(lookups.PostgresSimpleLookup): +class DateTimeRangeContains(PostgresOperatorLookup): """ Lookup for Date/DateTimeRange containment to cast the rhs to the correct type. """ lookup_name = 'contains' - operator = RangeOperators.CONTAINS + postgres_operator = RangeOperators.CONTAINS def process_rhs(self, compiler, connection): # Transform rhs value for db lookup. @@ -177,8 +178,8 @@ class DateTimeRangeContains(lookups.PostgresSimpleLookup): self.rhs = value.resolve_expression(compiler.query) return super().process_rhs(compiler, connection) - def as_sql(self, compiler, connection): - sql, params = super().as_sql(compiler, connection) + def as_postgresql(self, compiler, connection): + sql, params = super().as_postgresql(compiler, connection) # Cast the rhs if needed. cast_sql = '' if ( @@ -196,7 +197,7 @@ DateRangeField.register_lookup(DateTimeRangeContains) DateTimeRangeField.register_lookup(DateTimeRangeContains) -class RangeContainedBy(lookups.PostgresSimpleLookup): +class RangeContainedBy(PostgresOperatorLookup): lookup_name = 'contained_by' type_mapping = { 'smallint': 'int4range', @@ -207,7 +208,7 @@ class RangeContainedBy(lookups.PostgresSimpleLookup): 'date': 'daterange', 'timestamp with time zone': 'tstzrange', } - operator = RangeOperators.CONTAINED_BY + postgres_operator = RangeOperators.CONTAINED_BY def process_rhs(self, compiler, connection): rhs, rhs_params = super().process_rhs(compiler, connection) @@ -236,33 +237,33 @@ models.DecimalField.register_lookup(RangeContainedBy) @RangeField.register_lookup -class FullyLessThan(lookups.PostgresSimpleLookup): +class FullyLessThan(PostgresOperatorLookup): lookup_name = 'fully_lt' - operator = RangeOperators.FULLY_LT + postgres_operator = RangeOperators.FULLY_LT @RangeField.register_lookup -class FullGreaterThan(lookups.PostgresSimpleLookup): +class FullGreaterThan(PostgresOperatorLookup): lookup_name = 'fully_gt' - operator = RangeOperators.FULLY_GT + postgres_operator = RangeOperators.FULLY_GT @RangeField.register_lookup -class NotLessThan(lookups.PostgresSimpleLookup): +class NotLessThan(PostgresOperatorLookup): lookup_name = 'not_lt' - operator = RangeOperators.NOT_LT + postgres_operator = RangeOperators.NOT_LT @RangeField.register_lookup -class NotGreaterThan(lookups.PostgresSimpleLookup): +class NotGreaterThan(PostgresOperatorLookup): lookup_name = 'not_gt' - operator = RangeOperators.NOT_GT + postgres_operator = RangeOperators.NOT_GT @RangeField.register_lookup -class AdjacentToLookup(lookups.PostgresSimpleLookup): +class AdjacentToLookup(PostgresOperatorLookup): lookup_name = 'adjacent_to' - operator = RangeOperators.ADJACENT_TO + postgres_operator = RangeOperators.ADJACENT_TO @RangeField.register_lookup diff --git a/django/contrib/postgres/lookups.py b/django/contrib/postgres/lookups.py index 37630bc068..360e0c6a31 100644 --- a/django/contrib/postgres/lookups.py +++ b/django/contrib/postgres/lookups.py @@ -1,41 +1,33 @@ -from django.db.models import Lookup, Transform -from django.db.models.lookups import Exact, FieldGetDbPrepValueMixin +from django.db.models import Transform +from django.db.models.lookups import Exact, PostgresOperatorLookup from .search import SearchVector, SearchVectorExact, SearchVectorField -class PostgresSimpleLookup(FieldGetDbPrepValueMixin, Lookup): - def as_sql(self, qn, connection): - lhs, lhs_params = self.process_lhs(qn, connection) - rhs, rhs_params = self.process_rhs(qn, connection) - params = tuple(lhs_params) + tuple(rhs_params) - return '%s %s %s' % (lhs, self.operator, rhs), params - - -class DataContains(PostgresSimpleLookup): +class DataContains(PostgresOperatorLookup): lookup_name = 'contains' - operator = '@>' + postgres_operator = '@>' -class ContainedBy(PostgresSimpleLookup): +class ContainedBy(PostgresOperatorLookup): lookup_name = 'contained_by' - operator = '<@' + postgres_operator = '<@' -class Overlap(PostgresSimpleLookup): +class Overlap(PostgresOperatorLookup): lookup_name = 'overlap' - operator = '&&' + postgres_operator = '&&' -class HasKey(PostgresSimpleLookup): +class HasKey(PostgresOperatorLookup): lookup_name = 'has_key' - operator = '?' + postgres_operator = '?' prepare_rhs = False -class HasKeys(PostgresSimpleLookup): +class HasKeys(PostgresOperatorLookup): lookup_name = 'has_keys' - operator = '?&' + postgres_operator = '?&' def get_prep_lookup(self): return [str(item) for item in self.rhs] @@ -43,7 +35,7 @@ class HasKeys(PostgresSimpleLookup): class HasAnyKeys(HasKeys): lookup_name = 'has_any_keys' - operator = '?|' + postgres_operator = '?|' class Unaccent(Transform): @@ -63,9 +55,9 @@ class SearchLookup(SearchVectorExact): return lhs, lhs_params -class TrigramSimilar(PostgresSimpleLookup): +class TrigramSimilar(PostgresOperatorLookup): lookup_name = 'trigram_similar' - operator = '%%' + postgres_operator = '%%' class JSONExact(Exact): diff --git a/django/db/models/lookups.py b/django/db/models/lookups.py index 59e1b7211b..d32c891284 100644 --- a/django/db/models/lookups.py +++ b/django/db/models/lookups.py @@ -256,6 +256,17 @@ class FieldGetDbPrepValueIterableMixin(FieldGetDbPrepValueMixin): return sql, tuple(params) +class PostgresOperatorLookup(FieldGetDbPrepValueMixin, Lookup): + """Lookup defined by operators on PostgreSQL.""" + postgres_operator = None + + def as_postgresql(self, compiler, connection): + lhs, lhs_params = self.process_lhs(compiler, connection) + rhs, rhs_params = self.process_rhs(compiler, connection) + params = tuple(lhs_params) + tuple(rhs_params) + return '%s %s %s' % (lhs, self.postgres_operator, rhs), params + + @Field.register_lookup class Exact(FieldGetDbPrepValueMixin, BuiltinLookup): lookup_name = 'exact'