From 7174cf0b009711c41e5f76f6c0c68137898716a0 Mon Sep 17 00:00:00 2001 From: Mads Jensen Date: Fri, 12 Jul 2019 13:08:00 +0200 Subject: [PATCH] Refs #29824 -- Added RangeOperators helper class. --- django/contrib/postgres/fields/ranges.py | 29 ++++++++++++++++++------ docs/ref/contrib/postgres/fields.txt | 28 +++++++++++++++++++++++ docs/releases/3.0.txt | 4 +++- 3 files changed, 53 insertions(+), 8 deletions(-) diff --git a/django/contrib/postgres/fields/ranges.py b/django/contrib/postgres/fields/ranges.py index 9a8932bcee..21e982cedd 100644 --- a/django/contrib/postgres/fields/ranges.py +++ b/django/contrib/postgres/fields/ranges.py @@ -12,9 +12,24 @@ __all__ = [ 'RangeField', 'IntegerRangeField', 'BigIntegerRangeField', 'DecimalRangeField', 'DateTimeRangeField', 'DateRangeField', 'FloatRangeField', + 'RangeOperators', ] +class RangeOperators: + # https://www.postgresql.org/docs/current/functions-range.html#RANGE-OPERATORS-TABLE + EQUAL = '=' + NOT_EQUAL = '<>' + CONTAINS = '@>' + CONTAINED_BY = '<@' + OVERLAPS = '&&' + FULLY_LT = '<<' + FULLY_GT = '>>' + NOT_LT = '&>' + NOT_GT = '&<' + ADJACENT_TO = '-|-' + + class RangeField(models.Field): empty_strings_allowed = False @@ -155,7 +170,7 @@ class DateTimeRangeContains(lookups.PostgresSimpleLookup): type. """ lookup_name = 'contains' - operator = '@>' + operator = RangeOperators.CONTAINS def process_rhs(self, compiler, connection): # Transform rhs value for db lookup. @@ -193,7 +208,7 @@ class RangeContainedBy(lookups.PostgresSimpleLookup): 'date': 'daterange', 'timestamp with time zone': 'tstzrange', } - operator = '<@' + operator = RangeOperators.CONTAINED_BY def process_rhs(self, compiler, connection): rhs, rhs_params = super().process_rhs(compiler, connection) @@ -220,31 +235,31 @@ models.FloatField.register_lookup(RangeContainedBy) @RangeField.register_lookup class FullyLessThan(lookups.PostgresSimpleLookup): lookup_name = 'fully_lt' - operator = '<<' + operator = RangeOperators.FULLY_LT @RangeField.register_lookup class FullGreaterThan(lookups.PostgresSimpleLookup): lookup_name = 'fully_gt' - operator = '>>' + operator = RangeOperators.FULLY_GT @RangeField.register_lookup class NotLessThan(lookups.PostgresSimpleLookup): lookup_name = 'not_lt' - operator = '&>' + operator = RangeOperators.NOT_LT @RangeField.register_lookup class NotGreaterThan(lookups.PostgresSimpleLookup): lookup_name = 'not_gt' - operator = '&<' + operator = RangeOperators.NOT_GT @RangeField.register_lookup class AdjacentToLookup(lookups.PostgresSimpleLookup): lookup_name = 'adjacent_to' - operator = '-|-' + operator = RangeOperators.ADJACENT_TO @RangeField.register_lookup diff --git a/docs/ref/contrib/postgres/fields.txt b/docs/ref/contrib/postgres/fields.txt index 34c4a4892d..387eb0f02e 100644 --- a/docs/ref/contrib/postgres/fields.txt +++ b/docs/ref/contrib/postgres/fields.txt @@ -916,3 +916,31 @@ types. .. attribute:: range_type The psycopg2 range type to use. + +Range operators +--------------- + +.. versionadded:: 3.0 + +.. class:: RangeOperators + +PostgreSQL provides a set of SQL operators that can be used together with the +range data types (see `the PostgreSQL documentation for the full details of +range operators `_). This class is meant as a +convenient method to avoid typos. The operator names overlap with the names of +corresponding lookups. + +.. code-block:: python + + class RangeOperators: + EQUAL = '=' + NOT_EQUAL = '<>' + CONTAINS = '@>' + CONTAINED_BY = '<@' + OVERLAPS = '&&' + FULLY_LT = '<<' + FULLY_GT = '>>' + NOT_LT = '&>' + NOT_GT = '&<' + ADJACENT_TO = '-|-' diff --git a/docs/releases/3.0.txt b/docs/releases/3.0.txt index 5a1279219e..6aa21975bf 100644 --- a/docs/releases/3.0.txt +++ b/docs/releases/3.0.txt @@ -133,7 +133,9 @@ Minor features :mod:`django.contrib.postgres` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -* ... +* The new :class:`~django.contrib.postgres.fields.RangeOperators` helps to + avoid typos in SQL operators that can be used together with + :class:`~django.contrib.postgres.fields.RangeField`. :mod:`django.contrib.redirects` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~