Поля модели, специфичные для PostgreSQL
Все эти поля доступны из модуля django.contrib.postgres.fields.
Индексация этих полей
Index и Field.db_index оба создают индекс B-дерева, что не особенно полезно при запросе к сложным типам данных. Более подходящими являются индексы, такие как GinIndex и GistIndex, хотя выбор индекса зависит от используемых запросов. Как правило, GiST может быть хорошим выбором для полей диапазонов полей диапазонов и HStoreField, а GIN может быть полезен для ArrayField.
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>]>
Преобразования индексов
Преобразования индексов индексируют массив. Можно использовать любые неотрицательные целые числа. Нет ошибок, если индекс выходит за пределы 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. Прочитайте о соображениях производительности перед использованием.
Для использования
citext, используйте операциюCITextExtensionдля настройки расширения citext в 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ведет себя аналогично типуtextPostgreSQL.
HStoreField
-
class HStoreField(**options) -
Поле для хранения пар «ключ-значение». Используемый тип данных Python —
dict. Ключи должны быть строками, а значения могут быть строками или null (Noneв Python).Для использования этого поля необходимо:
- Добавить
'django.contrib.postgres'вINSTALLED_APPS. - Настроить расширение hstore в 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 данные представлены в их родном формате: словари, списки, строки, числа, булевы значения и
None.-
encoder -
Дополнительный класс кодирования JSON для сериализации типов данных, не поддерживаемых стандартным сериализатором JSON (
datetime,uuid, и т. д.). Например, вы можете использовать классDjangoJSONEncoderили любой другой подклассjson.JSONEncoder.При получении значения из базы данных оно будет в формате, выбранном пользовательским кодировщиком (чаще всего — строка), поэтому вам нужно будет предпринять дополнительные шаги для преобразования значения обратно в исходный тип данных (
Model.from_db()иField.from_db_value()— два возможных способа для этого). Ваша десериализация может потребовать учета того, что вы не можете быть уверены в типе входных данных. Например, вы рискуете получитьdatetime, который на самом деле был строкой, просто совпадающей по формату с выбранным форматом дляdatetime.
Если вы задаете для поля
default, убедитесь, что это вызываемый объект, например,dict(для пустого значения по умолчанию) или вызываемый объект, возвращающий словарь (например, функция). Неправильное использованиеdefault={}создаёт изменяемое значение по умолчанию, которое делится между всеми экземплярамиJSONField. -
Примечание
PostgreSQL имеет два собственных типа данных на основе JSON: json и jsonb. Основное различие между ними заключается в том, как они хранятся и как по ним можно выполнять поиск. Поле json PostgreSQL хранит исходное строковое представление JSON и должно декодироваться на лету при запросе по ключам. Поле jsonb хранится на основе фактической структуры JSON, что позволяет выполнять индексирование. Компромисс заключается в незначительных дополнительных затратах при записи в поле jsonb. JSONField использует jsonb.
Устарело начиная с версии 3.1: Используйте django.db.models.JSONField вместо этого.
Запросы к полю JSONField
См. Запросы к полю JSONField для получения подробной информации.
Диапазонные поля
Существует пять типов диапазонных полей, соответствующих встроенным типам диапазонов в PostgreSQL. Эти поля используются для хранения диапазона значений; например, начальной и конечной временных отметок события или диапазона возрастов, для которых подходит определённая активность.
Все диапазонные поля преобразуются в объекты psycopg2 Range в Python, но также принимают кортежи в качестве входных данных, если информация о границах не требуется. По умолчанию используется нижняя граница, включенная, а верхняя граница, исключённая, то есть [) (см. документацию PostgreSQL для получения подробной информации о различных границах).
IntegerRangeField
-
class IntegerRangeField(**options) -
Хранит диапазон целых чисел. Основано на
IntegerField. Представлено в базе данных какint4rangeи какNumericRangeв Python.Независимо от указанных границ при сохранении данных PostgreSQL всегда возвращает диапазон в канонической форме, включающей нижнюю границу и исключающей верхнюю границу, то есть
[).
BigIntegerRangeField
-
class BigIntegerRangeField(**options) -
Хранит диапазон больших целых чисел. Основан на
BigIntegerField. Представлен в базе данных какint8rangeи в Python какNumericRange.Независимо от указанных границ при сохранении данных, PostgreSQL всегда возвращает диапазон в канонической форме, которая включает нижнюю границу и исключает верхнюю границу, то есть
[).
DecimalRangeField
-
class DecimalRangeField(**options) -
Хранит диапазон значений с плавающей точкой. Основан на
DecimalField. Представлен в базе данных какnumrangeи в Python какNumericRange.
DateTimeRangeField
-
class DateTimeRangeField(**options) -
Хранит диапазон временных меток. Основан на
DateTimeField. Представлен в базе данных какtstzrangeи в Python какDateTimeTZRange.
DateRangeField
-
class DateRangeField(**options) -
Хранит диапазон дат. Основан на
DateField. Представлен в базе данных какdaterangeи в Python какDateRange.Независимо от указанных границ при сохранении данных, 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 также доступен для типов полей без диапазона: SmallAutoField, AutoField, BigAutoField, SmallIntegerField, IntegerField, BigIntegerField, DecimalField, 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>]>
Добавлена поддержка SmallAutoField, AutoField, BigAutoField, SmallIntegerField и DecimalField.
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 []>
lower_inc
Возвращает объекты с включительной или исключительной нижней границей в зависимости от переданного булевого значения. Можно комбинировать с валидными запросами для BooleanField.
>>> Event.objects.filter(ages__lower_inc=True) <QuerySet [<Event: Soft play>, <Event: Pub trip>]>
lower_inf
Возвращает объекты с неограниченной (бесконечной) или ограниченной нижней границей в зависимости от переданного булевого значения. Можно комбинировать с валидными запросами для BooleanField.
>>> Event.objects.filter(ages__lower_inf=True) <QuerySet []>
upper_inc
Возвращает объекты с включительной или исключительной верхней границей в зависимости от переданного булевого значения. Можно комбинировать с валидными запросами для BooleanField.
>>> Event.objects.filter(ages__upper_inc=True) <QuerySet []>
upper_inf
Возвращает объекты с неограниченной (бесконечной) или ограниченной верхней границей в зависимости от переданного булевого значения. Можно комбинировать с валидными запросами для BooleanField.
>>> Event.objects.filter(ages__upper_inf=True) <QuerySet [<Event: Pub trip>]>
Определение собственных типов диапазонов
PostgreSQL позволяет определять пользовательские типы диапазонов. Реализации полей модели и формы Django используют базовые классы ниже, а psycopg2 предоставляет register_range() для использования пользовательских типов диапазонов.
-
class RangeField(**options) -
Базовый класс для полей диапазона модели.
-
base_field -
Класс поля модели для использования.
-
range_type -
Тип диапазона psycopg2 для использования.
-
form_field -
Класс поля формы для использования. Должен быть подклассом
django.contrib.postgres.forms.BaseRangeField.
-
-
class django.contrib.postgres.forms.BaseRangeField -
Базовый класс для полей диапазона формы.
-
base_field -
Поле формы для использования.
-
range_type -
Тип диапазона psycopg2 для использования.
-
Операторы диапазонов
-
class RangeOperators
PostgreSQL предоставляет набор SQL операторов, которые могут использоваться вместе с типами данных диапазонов (см. документацию PostgreSQL для подробных сведений об операторах диапазонов). Этот класс предназначен как удобный способ избежать опечаток. Имена операторов совпадают с именами соответствующих поисков.
class RangeOperators:
EQUAL = '='
NOT_EQUAL = '<>'
CONTAINS = '@>'
CONTAINED_BY = '<@'
OVERLAPS = '&&'
FULLY_LT = '<<'
FULLY_GT = '>>'
NOT_LT = '&>'
NOT_GT = '&<'
ADJACENT_TO = '-|-'
Выражения RangeBoundary()
-
class RangeBoundary(inclusive_lower=True, inclusive_upper=False) -
-
inclusive_lower -
Если
True(по умолчанию), нижняя граница включена'[', в противном случае она исключена'('.
-
inclusive_upper -
Если
False(по умолчанию), верхняя граница исключена')', в противном случае она включена']'.
-
Выражение RangeBoundary() представляет грани диапазона. Его можно использовать с пользовательскими функциями диапазонов, которые ожидают границы, например, для определения ExclusionConstraint. Смотрите документацию PostgreSQL для получения более подробной информации.
© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/3.1/ref/contrib/postgres/fields/