Поля модели, специфичные для PostgreSQL¶
Все эти поля доступны из модуля django.contrib.postgres.fields
.
Индексирование этих полей¶
Index
и Field.db_index
оба создают индекс B-дерева, который не особенно полезен при запросах к сложным типам данных. Такие индексы, как GinIndex
и GistIndex
подходят лучше, хотя выбор индекса зависит от запросов, которые вы используете. В целом, GiST может быть хорошим выбором для range fields и HStoreField
, а GIN может быть полезен для ArrayField
и JSONField
.
ArrayField
¶
-
class
ArrayField
(base_field, size=None, **options)[исходный код]¶ Поле для хранения списков данных. Можно использовать большинство типов полей, просто передайте другой экземпляр поля в качестве
base_field
. Вы также можете указатьsize
.ArrayField
могут быть вложенными для хранения многомерных массивов.Если вы задаете полю значение
default
, убедитесь, что это вызываемая переменная, такая какlist
(для пустого значения по умолчанию) или вызываемая переменная, возвращающая список (например, функция). Неправильное использованиеdefault=[]
создает изменяемое значение по умолчанию, которое разделяется между всеми экземплярамиArrayField
.-
base_field
¶ Это необходимый аргумент.
Определяет базовый тип данных и поведение массива. Это должен быть экземпляр подкласса
Field
. Например, это может бытьIntegerField
илиCharField
. Допускается использование большинства типов полей, за исключением тех, которые работают с реляционными данными (ForeignKey
,OneToOneField
иManyToManyField
).Возможно вложение полей массива - вы можете указать экземпляр
ArrayField
в качествеbase_field
. Например:from django.contrib.postgres.fields import ArrayField from django.db import models class ChessBoard(models.Model): board = ArrayField( ArrayField( models.CharField(max_length=10, blank=True), size=8, ), size=8, )
Преобразование значений между базой данных и моделью, проверка данных и конфигурации, а также сериализация - все это делегируется базовому полю.
-
size
¶ Это необязательный аргумент.
Если этот параметр передан, массив будет иметь максимальный размер, как указано. Это значение будет передано в базу данных, хотя в настоящее время PostgreSQL не применяет это ограничение.
-
Примечание
При вложении ArrayField
, независимо от того, используете ли вы параметр size или нет, PostgreSQL требует, чтобы массивы были прямоугольными:
from django.contrib.postgres.fields import ArrayField
from django.db import models
class Board(models.Model):
pieces = ArrayField(ArrayField(models.IntegerField()))
# Valid
Board(pieces=[
[2, 3],
[2, 1],
])
# Not valid
Board(pieces=[
[2, 3],
[2],
])
Если требуются неправильные формы, то базовое поле следует сделать нулевым, а значения дополнить символом None
.
Запрос ArrayField
¶
Для ArrayField
существует ряд пользовательских поисков и преобразований. Мы будем использовать следующий пример модели:
from django.contrib.postgres.fields import ArrayField
from django.db import models
class Post(models.Model):
name = models.CharField(max_length=200)
tags = ArrayField(models.CharField(max_length=200), blank=True)
def __str__(self):
return self.name
contains
¶
Поиск contains
переопределяется на ArrayField
. Возвращаемыми объектами будут те, в которых переданные значения являются подмножеством данных. Используется оператор SQL @>
. Например:
>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
>>> Post.objects.create(name='Second post', tags=['thoughts'])
>>> Post.objects.create(name='Third post', tags=['tutorial', 'django'])
>>> Post.objects.filter(tags__contains=['thoughts'])
<QuerySet [<Post: First post>, <Post: Second post>]>
>>> Post.objects.filter(tags__contains=['django'])
<QuerySet [<Post: First post>, <Post: Third post>]>
>>> Post.objects.filter(tags__contains=['django', 'thoughts'])
<QuerySet [<Post: First post>]>
contained_by
¶
Это обратный вариант поиска contains
- возвращаются объекты, данные которых являются подмножеством переданных значений. В нем используется оператор SQL <@
. Например:
>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
>>> Post.objects.create(name='Second post', tags=['thoughts'])
>>> Post.objects.create(name='Third post', tags=['tutorial', 'django'])
>>> Post.objects.filter(tags__contained_by=['thoughts', 'django'])
<QuerySet [<Post: First post>, <Post: Second post>]>
>>> Post.objects.filter(tags__contained_by=['thoughts', 'django', 'tutorial'])
<QuerySet [<Post: First post>, <Post: Second post>, <Post: Third post>]>
overlap
¶
Возвращает объекты, в которых данные разделяют любые результаты с переданными значениями. Использует оператор SQL &&
. Например:
>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
>>> Post.objects.create(name='Second post', tags=['thoughts'])
>>> Post.objects.create(name='Third post', tags=['tutorial', 'django'])
>>> Post.objects.filter(tags__overlap=['thoughts'])
<QuerySet [<Post: First post>, <Post: Second post>]>
>>> Post.objects.filter(tags__overlap=['thoughts', 'tutorial'])
<QuerySet [<Post: First post>, <Post: Second post>, <Post: Third post>]>
len
¶
Возвращает длину массива. После этого доступны те же функции поиска, что и для IntegerField
. Например:
>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
>>> Post.objects.create(name='Second post', tags=['thoughts'])
>>> Post.objects.filter(tags__len=1)
<QuerySet [<Post: Second post>]>
Преобразования индексов¶
Index преобразует индекс в массив. Можно использовать любое неотрицательное целое число. Ошибки нет, если оно превышает size
массива. После преобразования доступны поиски из массива base_field
. Например:
>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
>>> Post.objects.create(name='Second post', tags=['thoughts'])
>>> Post.objects.filter(tags__0='thoughts')
<QuerySet [<Post: First post>, <Post: Second post>]>
>>> Post.objects.filter(tags__1__iexact='Django')
<QuerySet [<Post: First post>]>
>>> Post.objects.filter(tags__276='javascript')
<QuerySet []>
Примечание
PostgreSQL использует индексацию на основе 1 для полей массива при написании необработанного SQL. Однако эти индексы и индексы, используемые в slices
, используют индексацию на основе 0, чтобы соответствовать Python.
Преобразования срезов¶
Преобразования среза берут срез массива. Можно использовать любые два неотрицательных целых числа, разделенных одним знаком подчеркивания. Поиск, доступный после преобразования, не изменяется. Например:
>>> Post.objects.create(name='First post', tags=['thoughts', 'django'])
>>> Post.objects.create(name='Second post', tags=['thoughts'])
>>> Post.objects.create(name='Third post', tags=['django', 'python', 'thoughts'])
>>> Post.objects.filter(tags__0_1=['thoughts'])
<QuerySet [<Post: First post>, <Post: Second post>]>
>>> Post.objects.filter(tags__0_2__contains=['thoughts'])
<QuerySet [<Post: First post>, <Post: Second post>]>
Примечание
PostgreSQL использует индексацию на основе 1 для полей массива при написании необработанного SQL. Однако эти срезы и срезы, используемые в indexes
, используют индексацию на основе 0, чтобы соответствовать Python.
Многомерные массивы с индексами и срезами
PostgreSQL имеет довольно эзотерическое поведение при использовании индексов и срезов на многомерных массивах. Использование индексов для достижения конечных базовых данных всегда будет работать, но большинство других срезов ведут себя странно на уровне базы данных и не могут поддерживаться логически последовательным образом в Django.
CIText
поля¶
-
class
CIText
(**options)[исходный код]¶ Миксин для создания нечувствительных к регистру текстовых полей, поддерживаемых типом citext. Перед использованием прочитайте о the performance considerations.
Чтобы использовать
citext
, используйте операциюCITextExtension
для setup the citext extension в PostgreSQL перед первой операцией миграцииCreateModel
.Если вы используете
ArrayField
полейCIText
, вы должны добавить'django.contrib.postgres'
в вашиINSTALLED_APPS
, иначе значения полей будут отображаться как строки типа'{thoughts,django}'
.Предоставляется несколько полей, использующих миксин:
-
class
CICharField
(**options)[исходный код]¶
-
class
CIEmailField
(**options)[исходный код]¶
-
class
CITextField
(**options)[исходный код]¶ Эти поля являются подклассами
CharField
,EmailField
иTextField
, соответственно.max_length
не будет применяться в базе данных, посколькуcitext
ведет себя аналогично типу PostgreSQLtext
.
HStoreField
¶
-
class
HStoreField
(**options)[исходный код]¶ Поле для хранения пар ключ-значение. Используемый тип данных в Python -
dict
. Ключи должны быть строками, а значения могут быть либо строками, либо нулями (None
в Python).Чтобы использовать это поле, вам необходимо:
- Добавьте
'django.contrib.postgres'
в вашINSTALLED_APPS
. - Setup the hstore extension в PostgreSQL.
Вы увидите ошибку типа
can't adapt type 'dict'
, если пропустите первый шаг, илиtype "hstore" does not exist
, если пропустите второй.- Добавьте
Примечание
В некоторых случаях может быть полезно потребовать или ограничить ключи, которые действительны для данного поля. Это можно сделать с помощью функции KeysValidator
.
Запрос HStoreField
¶
В дополнение к возможности запроса по ключу, для HStoreField
доступен ряд пользовательских поисков.
Мы будем использовать следующий пример модели:
from django.contrib.postgres.fields import HStoreField
from django.db import models
class Dog(models.Model):
name = models.CharField(max_length=200)
data = HStoreField()
def __str__(self):
return self.name
Поиск ключей¶
Чтобы сделать запрос на основе заданного ключа, достаточно использовать этот ключ в качестве имени поиска:
>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
>>> Dog.objects.create(name='Meg', data={'breed': 'collie'})
>>> Dog.objects.filter(data__breed='collie')
<QuerySet [<Dog: Meg>]>
После поиска ключа можно выполнить цепочку других поисков:
>>> Dog.objects.filter(data__breed__contains='l')
<QuerySet [<Dog: Rufus>, <Dog: Meg>]>
Если ключ, по которому вы хотите сделать запрос, не совпадает с именем другого поиска, вместо него нужно использовать поиск hstorefield.contains
.
Предупреждение
Поскольку любая строка может быть ключом в значении hstore, любой поиск, кроме перечисленных ниже, будет интерпретироваться как поиск ключа. Никаких ошибок при этом не возникает. Будьте предельно внимательны к опечаткам и всегда проверяйте, что ваши запросы работают так, как вы задумали.
contains
¶
Поиск contains
переопределяется на HStoreField
. Возвращаемыми объектами являются те, в которых заданные dict
> пары ключ-значение все содержатся в поле. Используется оператор SQL @>
. Например:
>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador', 'owner': 'Bob'})
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
>>> Dog.objects.create(name='Fred', data={})
>>> Dog.objects.filter(data__contains={'owner': 'Bob'})
<QuerySet [<Dog: Rufus>, <Dog: Meg>]>
>>> Dog.objects.filter(data__contains={'breed': 'collie'})
<QuerySet [<Dog: Meg>]>
contained_by
¶
Это обратный вариант поиска contains
- возвращаются те объекты, в которых пары ключ-значение объекта являются подмножеством пар в переданном значении. Здесь используется оператор SQL <@
. Например:
>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador', 'owner': 'Bob'})
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
>>> Dog.objects.create(name='Fred', data={})
>>> Dog.objects.filter(data__contained_by={'breed': 'collie', 'owner': 'Bob'})
<QuerySet [<Dog: Meg>, <Dog: Fred>]>
>>> Dog.objects.filter(data__contained_by={'breed': 'collie'})
<QuerySet [<Dog: Fred>]>
has_key
¶
Возвращает объекты, в данных которых находится заданный ключ. Использует оператор SQL ?
. Например:
>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
>>> Dog.objects.filter(data__has_key='owner')
<QuerySet [<Dog: Meg>]>
has_any_keys
¶
Возвращает объекты, в данных которых есть любой из заданных ключей. Использует оператор SQL ?|
. Например:
>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
>>> Dog.objects.create(name='Meg', data={'owner': 'Bob'})
>>> Dog.objects.create(name='Fred', data={})
>>> Dog.objects.filter(data__has_any_keys=['owner', 'breed'])
<QuerySet [<Dog: Rufus>, <Dog: Meg>]>
has_keys
¶
Возвращает объекты, в данных которых есть все заданные ключи. Использует оператор SQL ?&
. Например:
>>> Dog.objects.create(name='Rufus', data={})
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
>>> Dog.objects.filter(data__has_keys=['breed', 'owner'])
<QuerySet [<Dog: Meg>]>
keys
¶
Возвращает объекты, где массив ключей является заданным значением. Обратите внимание, что порядок не гарантируется, поэтому это преобразование полезно использовать в основном в сочетании с поиском по ArrayField
. Использует SQL-функцию akeys()
. Например:
>>> Dog.objects.create(name='Rufus', data={'toy': 'bone'})
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
>>> Dog.objects.filter(data__keys__overlap=['breed', 'toy'])
<QuerySet [<Dog: Rufus>, <Dog: Meg>]>
values
¶
Возвращает объекты, где массив значений является заданным значением. Обратите внимание, что порядок не гарантируется, поэтому это преобразование полезно использовать в основном в сочетании с поиском по ArrayField
. Использует SQL-функцию avalues()
. Например:
>>> Dog.objects.create(name='Rufus', data={'breed': 'labrador'})
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': 'Bob'})
>>> Dog.objects.filter(data__values__contains=['collie'])
<QuerySet [<Dog: Meg>]>
JSONField
¶
-
class
JSONField
(encoder=None, **options)[исходный код]¶ Поле для хранения данных в кодировке JSON. В Python данные представляются в родном для Python формате: словари, списки, строки, числа, булевы и
None
.-
encoder
¶ Дополнительный класс JSON-кодирования для сериализации типов данных, не поддерживаемых стандартным JSON-сериализатором (
datetime
,uuid
и т.д.). Например, вы можете использовать классDjangoJSONEncoder
или любой другой подклассjson.JSONEncoder
.Когда значение будет получено из базы данных, оно будет в формате, выбранном пользовательским кодировщиком (чаще всего строка), поэтому вам потребуется предпринять дополнительные шаги для преобразования значения обратно в исходный тип данных (
Model.from_db()
иField.from_db_value()
- два возможных хука для этой цели). Десериализация может потребовать учета того факта, что вы не можете быть уверены в типе входных данных. Например, вы рискуете вернутьdatetime
, который на самом деле был строкой, которая просто оказалась в том же формате, который был выбран дляdatetime
s.
Если вы задаете полю значение
default
, убедитесь, что это вызываемая переменная, такая какdict
(для пустого значения по умолчанию) или вызываемая переменная, которая возвращает dict (например, функция). Неправильное использованиеdefault={}
создает изменяемое значение по умолчанию, которое разделяется между всеми экземплярамиJSONField
.-
Примечание
PostgreSQL имеет два собственных типа данных на основе JSON: json
и jsonb
. Основное различие между ними заключается в том, как они хранятся и как к ним можно обращаться. Поле json
в PostgreSQL хранится как оригинальное строковое представление JSON и должно быть декодировано на лету при запросе на основе ключей. Поле jsonb
хранится на основе фактической структуры JSON, что позволяет осуществлять индексирование. Компромиссом является небольшая дополнительная стоимость записи в поле jsonb
. В JSONField
используется jsonb
.
Запрос JSONField
¶
Мы будем использовать следующий пример модели:
from django.contrib.postgres.fields import JSONField
from django.db import models
class Dog(models.Model):
name = models.CharField(max_length=200)
data = JSONField()
def __str__(self):
return self.name
Поиск ключей, индексов и путей¶
Чтобы сделать запрос на основе заданного ключа словаря, просто используйте этот ключ в качестве имени поиска:
>>> Dog.objects.create(name='Rufus', data={
... 'breed': 'labrador',
... 'owner': {
... 'name': 'Bob',
... 'other_pets': [{
... 'name': 'Fishy',
... }],
... },
... })
>>> Dog.objects.create(name='Meg', data={'breed': 'collie', 'owner': None})
>>> Dog.objects.filter(data__breed='collie')
<QuerySet [<Dog: Meg>]>
Несколько ключей могут быть соединены вместе для формирования поиска пути:
>>> Dog.objects.filter(data__owner__name='Bob')
<QuerySet [<Dog: Rufus>]>
Если ключ является целым числом, он будет интерпретирован как поиск индекса в массиве:
>>> Dog.objects.filter(data__owner__other_pets__0__name='Fishy')
<QuerySet [<Dog: Rufus>]>
Если ключ, по которому вы хотите выполнить запрос, не совпадает с именем другого поиска, используйте вместо него поиск jsonfield.contains
.
Если используется только один ключ или индекс, то используется оператор SQL ->
. Если используется несколько операторов, то используется оператор #>
.
Чтобы запросить null
в данных JSON, используйте None
в качестве значения:
>>> Dog.objects.filter(data__owner=None)
<QuerySet [<Dog: Meg>]>
Для поиска отсутствующих ключей используйте поиск isnull
:
>>> Dog.objects.create(name='Shep', data={'breed': 'collie'})
>>> Dog.objects.filter(data__owner__isnull=True)
<QuerySet [<Dog: Shep>]>
В старых версиях использование None
в качестве значения поиска соответствовало объектам, не имеющим ключа, а не объектам, имеющим ключ со значением None
.
Предупреждение
Поскольку ключом в объекте JSON может быть любая строка, любой поиск, кроме перечисленных ниже, будет интерпретироваться как поиск ключа. Никаких ошибок при этом не возникает. Будьте предельно внимательны к опечаткам и всегда проверяйте, что ваши запросы работают так, как вы задумали.
Сдерживание и ключевые операции¶
JSONField
разделяет поиск, относящийся к сдерживанию и ключам, с HStoreField
.
contains
(принимает любой JSON, а не только словарь строк)contained_by
(принимает любой JSON, а не только словарь строк)has_key
has_any_keys
has_keys
Поля диапазона¶
Существует пять типов полей диапазона, соответствующих встроенным типам диапазонов в PostgreSQL. Эти поля используются для хранения диапазона значений; например, временные метки начала и окончания события или диапазон возрастов, для которых подходит то или иное мероприятие.
Все поля диапазона переводятся в psycopg2 Range objects в Python, но также могут принимать кортежи в качестве входных данных, если информация о границах не требуется. По умолчанию нижняя граница включена, верхняя исключена; то есть, [)
.
IntegerRangeField
¶
-
class
IntegerRangeField
(**options)[исходный код]¶ Хранит диапазон целых чисел. Основан на значении
IntegerField
. Представляется символомint4range
в базе данных иNumericRange
в Python.Независимо от границ, указанных при сохранении данных, PostgreSQL всегда возвращает диапазон в канонической форме, которая включает нижнюю границу и исключает верхнюю; то есть
[)
.
BigIntegerRangeField
¶
-
class
BigIntegerRangeField
(**options)[исходный код]¶ Хранит диапазон больших целых чисел. Основан на
BigIntegerField
. Представляется символомint8range
в базе данных иNumericRange
в Python.Независимо от границ, указанных при сохранении данных, PostgreSQL всегда возвращает диапазон в канонической форме, которая включает нижнюю границу и исключает верхнюю; то есть
[)
.
DecimalRangeField
¶
-
class
DecimalRangeField
(**options)[исходный код]¶ - New in Django 2.2.
Хранит диапазон значений с плавающей точкой. Основан на значении
DecimalField
. Представляется символомnumrange
в базе данных иNumericRange
в Python.
FloatRangeField
¶
-
class
FloatRangeField
(**options)¶ Хранит диапазон значений с плавающей точкой. Основан на значении
FloatField
. Представляется символомnumrange
в базе данных иNumericRange
в Python.Не рекомендуется, начиная с версии 2.2: Вместо этого используйте
DecimalRangeField
.
DateTimeRangeField
¶
-
class
DateTimeRangeField
(**options)[исходный код]¶ Хранит диапазон временных меток. Основан на значении
DateTimeField
. Представляется символомtstzrange
в базе данных иDateTimeTZRange
в Python.
DateRangeField
¶
-
class
DateRangeField
(**options)[исходный код]¶ Хранит диапазон дат. Основан на значении
DateField
. Представляется символомdaterange
в базе данных иDateRange
в Python.Независимо от границ, указанных при сохранении данных, PostgreSQL всегда возвращает диапазон в канонической форме, которая включает нижнюю границу и исключает верхнюю; то есть
[)
.
Запрос полей диапазона¶
Для полей диапазона существует ряд пользовательских поисков и преобразований. Они доступны для всех вышеперечисленных полей, но мы будем использовать следующий пример модели:
from django.contrib.postgres.fields import IntegerRangeField
from django.db import models
class Event(models.Model):
name = models.CharField(max_length=200)
ages = IntegerRangeField()
start = models.DateTimeField()
def __str__(self):
return self.name
Мы также будем использовать следующие примеры объектов:
>>> import datetime
>>> from django.utils import timezone
>>> now = timezone.now()
>>> Event.objects.create(name='Soft play', ages=(0, 10), start=now)
>>> Event.objects.create(name='Pub trip', ages=(21, None), start=now - datetime.timedelta(days=1))
и NumericRange
:
>>> from psycopg2.extras import NumericRange
Функции сдерживания¶
Как и для других полей PostgreSQL, существует три стандартных оператора сдерживания: contains
, contained_by
и overlap
, использующие операторы SQL @>
, <@
и &&
соответственно.
contains
¶
>>> Event.objects.filter(ages__contains=NumericRange(4, 5))
<QuerySet [<Event: Soft play>]>
contained_by
¶
>>> Event.objects.filter(ages__contained_by=NumericRange(0, 15))
<QuerySet [<Event: Soft play>]>
Поиск contained_by
также доступен для недиапазонных типов полей: IntegerField
, BigIntegerField
, FloatField
, DateField
и DateTimeField
. Например:
>>> from psycopg2.extras import DateTimeTZRange
>>> Event.objects.filter(start__contained_by=DateTimeTZRange(
... timezone.now() - datetime.timedelta(hours=1),
... timezone.now() + datetime.timedelta(hours=1),
... )
<QuerySet [<Event: Soft play>]>
overlap
¶
>>> Event.objects.filter(ages__overlap=NumericRange(8, 12))
<QuerySet [<Event: Soft play>]>
Функции сравнения¶
Поля диапазона поддерживают стандартный поиск: lt
, gt
, lte
и gte
. Они не особенно полезны - сначала сравниваются нижние границы, а затем, при необходимости, верхние. Эта же стратегия используется для упорядочивания по полю диапазона. Лучше использовать специальные операторы сравнения диапазонов.
fully_lt
¶
Возвращенный диапазон строго меньше переданного диапазона. Другими словами, все точки в возвращаемом диапазоне меньше, чем все точки в передаваемом диапазоне.
>>> Event.objects.filter(ages__fully_lt=NumericRange(11, 15))
<QuerySet [<Event: Soft play>]>
fully_gt
¶
Возвращенный диапазон строго больше переданного диапазона. Другими словами, все точки в возвращаемом диапазоне больше, чем все точки в передаваемом диапазоне.
>>> Event.objects.filter(ages__fully_gt=NumericRange(11, 15))
<QuerySet [<Event: Pub trip>]>
not_lt
¶
Возвращаемые диапазоны не содержат точек меньше, чем переданный диапазон, то есть нижняя граница возвращаемого диапазона не меньше нижней границы переданного диапазона.
>>> Event.objects.filter(ages__not_lt=NumericRange(0, 15))
<QuerySet [<Event: Soft play>, <Event: Pub trip>]>
not_gt
¶
Возвращаемые диапазоны не содержат точек, превышающих переданный диапазон, то есть верхняя граница возвращаемого диапазона не более верхней границы переданного диапазона.
>>> Event.objects.filter(ages__not_gt=NumericRange(3, 10))
<QuerySet [<Event: Soft play>]>
adjacent_to
¶
Возвращаемые диапазоны имеют общую границу с переданным диапазоном.
>>> Event.objects.filter(ages__adjacent_to=NumericRange(10, 21))
<QuerySet [<Event: Soft play>, <Event: Pub trip>]>
Запрос с использованием границ¶
Для использования в запросах доступны три преобразования. Вы можете извлечь нижнюю или верхнюю границу или сделать запрос на основе пустоты.
startswith
¶
Возвращаемые объекты имеют заданную нижнюю границу. Могут быть соединены в цепочку с действительными поисками для базового поля.
>>> Event.objects.filter(ages__startswith=21)
<QuerySet [<Event: Pub trip>]>
endswith
¶
Возвращаемые объекты имеют заданную верхнюю границу. Могут быть соединены в цепочку с действительными поисками для базового поля.
>>> Event.objects.filter(ages__endswith=10)
<QuerySet [<Event: Soft play>]>
isempty
¶
Возвращаемые объекты - пустые диапазоны. Может быть соединен в цепочку с действительными поисками для BooleanField
.
>>> Event.objects.filter(ages__isempty=True)
<QuerySet []>
Определение собственных типов диапазонов¶
PostgreSQL позволяет определять пользовательские типы диапазонов. Реализации модели и поля формы Django используют базовые классы, приведенные ниже, а psycopg2 предоставляет register_range()
для разрешения использования пользовательских типов диапазонов.
-
class
RangeField
(**options)[исходный код]¶ Базовый класс для полей модельного ряда.
-
base_field
¶ Класс поля модели для использования.
-
range_type
¶ Используемый тип диапазона psycopg2.
-
form_field
¶ Используемый класс поля формы. Должен быть подклассом
django.contrib.postgres.forms.BaseRangeField
.
-