Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 17 additions & 16 deletions django/contrib/postgres/fields/ranges.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

from django.contrib.postgres import forms, lookups
from django.db import models
from django.db.models.lookups import PostgresOperatorLookup

from .utils import AttributeSetter

Expand Down Expand Up @@ -161,13 +162,13 @@ def db_type(self, connection):
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.
Expand All @@ -177,8 +178,8 @@ def process_rhs(self, compiler, connection):
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 (
Expand All @@ -196,7 +197,7 @@ def as_sql(self, compiler, connection):
DateTimeRangeField.register_lookup(DateTimeRangeContains)


class RangeContainedBy(lookups.PostgresSimpleLookup):
class RangeContainedBy(PostgresOperatorLookup):
lookup_name = 'contained_by'
type_mapping = {
'smallint': 'int4range',
Expand All @@ -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)
Expand Down Expand Up @@ -236,33 +237,33 @@ def get_prep_lookup(self):


@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
Expand Down
38 changes: 15 additions & 23 deletions django/contrib/postgres/lookups.py
Original file line number Diff line number Diff line change
@@ -1,49 +1,41 @@
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]


class HasAnyKeys(HasKeys):
lookup_name = 'has_any_keys'
operator = '?|'
postgres_operator = '?|'


class Unaccent(Transform):
Expand All @@ -63,9 +55,9 @@ def process_lhs(self, qn, connection):
return lhs, lhs_params


class TrigramSimilar(PostgresSimpleLookup):
class TrigramSimilar(PostgresOperatorLookup):
lookup_name = 'trigram_similar'
operator = '%%'
postgres_operator = '%%'


class JSONExact(Exact):
Expand Down
11 changes: 11 additions & 0 deletions django/db/models/lookups.py
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,17 @@ def batch_process_rhs(self, compiler, connection, rhs=None):
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'
Expand Down