Поля моделей, специфичные для 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) и файловые поля (FileFieldиImageField).Возможна вложенность полей массива — можно указать экземпляр
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],
])
Если требуются непрямоугольные формы, то базовое поле следует сделать допускающим значение NULL, и значения дополнить 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) -
Mixin для создания регистронезависимых текстовых полей, поддерживаемых типом citext. Прочитайте о соображениях производительности перед использованием.
Чтобы использовать
citext, используйте операциюCITextExtensionдля настройки расширения citext в PostgreSQL перед первой миграциейCreateModel.Если вы используете
ArrayFieldполейCIText, необходимо добавить'django.contrib.postgres'вINSTALLED_APPS, иначе значения полей будут отображаться как строки, например,'{thoughts,django}'.Предоставляется несколько полей, использующих mixin:
-
class CICharField(**options)
-
class CIEmailField(**options)
-
class CITextField(**options) -
Эти поля являются подклассами
CharField,EmailFieldиTextField, соответственно.max_lengthне будут проверяться в базе данных, так какcitextведет себя аналогично типуtextв PostgreSQL.
Регистронезависимые сортировки
В PostgreSQL 12+ предпочтительнее использовать недетерминированные сортировки вместо расширения citext. Вы можете создать их, используя операцию миграции CreateCollation. Более подробную информацию см. в разделе Управление сортировками с помощью миграций и документации PostgreSQL о недетерминированных сортировках.
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.
KeyTransform() выражение
-
class hstore.KeyTransform(key_name, *args, **kwargs)
Возвращает значение заданного key_name. Это позволяет аннотировать значение ключа. Например:
>>> from django.contrib.postgres.fields.hstore import KeyTransform
>>> Dog.objects.create(name="Rufus", data={"breed": "labrador"})
>>> Dog.objects.create(name="Meg", data={"breed": "collie", "owner": "Bob"})
>>> rufus = Dog.objects.annotate(breed=KeyTransform("breed", "data"))[0]
>>> rufus.breed
'labrador'
Запросы к полю 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 вместо этого.
Примечание
Преобразования ключей также могут быть объединены с: contains, icontains, endswith, iendswith, iexact, regex, iregex, startswith и istartswith методами поиска.
Предупреждение
Поскольку любой строковый ключ может быть ключом в значении 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-функцию avals(). Например:
>>> 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>]>
Поля диапазонов
Существует пять типов полей диапазонов, соответствующих встроенным типам диапазонов в PostgreSQL. Эти поля используются для хранения диапазона значений; например, начальной и конечной временных меток события или диапазона возрастов, для которых подходит данная активность.
Все поля диапазонов переводятся в объекты psycopg2 Range в Python, но также принимают кортежи в качестве входных данных, если информация о границах не требуется. По умолчанию нижняя граница включена, верхняя граница исключена, то есть [) (см. документацию PostgreSQL для получения подробной информации о различных границах). Границы по умолчанию могут быть изменены для полей диапазонов, не являющихся дискретными (DateTimeRangeField и DecimalRangeField), используя аргумент default_bounds.
IntegerRangeField
-
class IntegerRangeField(**options) -
Хранит диапазон целых чисел. Основано на
IntegerField. Представлено в базе данных какint4rangeи какNumericRangeв Python.Независимо от указанных границ при сохранении данных, PostgreSQL всегда возвращает диапазон в канонической форме, включающей нижнюю границу и исключающей верхнюю, то есть
[).
BigIntegerRangeField
-
class BigIntegerRangeField(**options) -
Хранит диапазон больших целых чисел. Основано на
BigIntegerField. Представлено в базе данных какint8rangeи какNumericRangeв Python.Независимо от указанных границ при сохранении данных, PostgreSQL всегда возвращает диапазон в канонической форме, включающей нижнюю границу и исключающей верхнюю, то есть
[).
DecimalRangeField
-
class DecimalRangeField(default_bounds='[)', **options) -
Хранит диапазон значений с плавающей запятой. Основан на
DecimalField. Представлен в базе данных какnumrangeи в Python какNumericRange.-
default_bounds -
Новое в Django 4.1.
Необязательно. Значение
boundsдля списков и кортежей. По умолчанию нижняя граница включена, верхняя — исключена, то есть[)(см. документацию PostgreSQL для подробностей о различных границах).default_boundsне используется дляNumericRangeвходных данных.
-
DateTimeRangeField
-
class DateTimeRangeField(default_bounds='[)', **options) -
Хранит диапазон временных меток. Основан на
DateTimeField. Представлен в базе данных какtstzrangeи в Python какDateTimeTZRange.-
default_bounds -
Новое в Django 4.1.
Необязательно. Значение
boundsдля списков и кортежей. По умолчанию нижняя граница включена, верхняя — исключена, то есть[)(см. документацию PostgreSQL для подробностей о различных границах).default_boundsне используется для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>]>
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/4.1/ref/contrib/postgres/fields/