Spec-Zone.ru › Django 3.1

Функции базы данных

Классы, описанные ниже, предоставляют пользователям возможность использовать функции, предоставляемые основной базой данных, в качестве аннотаций, агрегаций или фильтров в Django. Функции также являются выражениями, поэтому их можно использовать и комбинировать с другими выражениями, такими как функции агрегации.

В примерах каждой функции мы будем использовать следующую модель:

class Author(models.Model):
    name = models.CharField(max_length=50)
    age = models.PositiveIntegerField(null=True, blank=True)
    alias = models.CharField(max_length=50, null=True, blank=True)
    goes_by = models.CharField(max_length=50, null=True, blank=True)

Мы обычно не рекомендуем разрешать null=True для CharField, так как это позволяет полю иметь два «пустых значения», но это важно для примера Coalesce ниже.

Функции сравнения и преобразования

Cast

class Cast(expression, output_field)

Принудительно задает тип результата expression на тип из output_field.

Пример использования:

>>> from django.db.models import FloatField
>>> from django.db.models.functions import Cast
>>> Author.objects.create(age=25, name='Margaret Smith')
>>> author = Author.objects.annotate(
...    age_as_float=Cast('age', output_field=FloatField()),
... ).get()
>>> print(author.age_as_float)
25.0

Coalesce

class Coalesce(*expressions, **extra)

Принимает список из по крайней мере двух имен полей или выражений и возвращает первое значение, отличное от NULL (обратите внимание, что пустая строка не считается значением NULL). Каждый аргумент должен иметь одинаковый тип, поэтому смешивание текста и чисел приведет к ошибке базы данных.

Примеры использования:

>>> # Get a screen name from least to most public
>>> from django.db.models import Sum, Value as V
>>> from django.db.models.functions import Coalesce
>>> Author.objects.create(name='Margaret Smith', goes_by='Maggie')
>>> author = Author.objects.annotate(
...    screen_name=Coalesce('alias', 'goes_by', 'name')).get()
>>> print(author.screen_name)
Maggie

>>> # Prevent an aggregate Sum() from returning None
>>> aggregated = Author.objects.aggregate(
...    combined_age=Coalesce(Sum('age'), V(0)),
...    combined_age_default=Sum('age'))
>>> print(aggregated['combined_age'])
0
>>> print(aggregated['combined_age_default'])
None

Предупреждение

Значение Python, переданное Coalesce в MySQL, может быть преобразовано в неправильный тип, если явно не преобразовано к правильному типу базы данных:

>>> from django.db.models import DateTimeField
>>> from django.db.models.functions import Cast, Coalesce
>>> from django.utils import timezone
>>> now = timezone.now()
>>> Coalesce('updated', Cast(now, DateTimeField()))

Greatest

class Greatest(*expressions, **extra)

Принимает список из по крайней мере двух имен полей или выражений и возвращает наибольшее значение. Каждый аргумент должен иметь одинаковый тип, поэтому смешивание текста и чисел приведет к ошибке базы данных.

Пример использования:

class Blog(models.Model):
    body = models.TextField()
    modified = models.DateTimeField(auto_now=True)

class Comment(models.Model):
    body = models.TextField()
    modified = models.DateTimeField(auto_now=True)
    blog = models.ForeignKey(Blog, on_delete=models.CASCADE)

>>> from django.db.models.functions import Greatest
>>> blog = Blog.objects.create(body='Greatest is the best.')
>>> comment = Comment.objects.create(body='No, Least is better.', blog=blog)
>>> comments = Comment.objects.annotate(last_updated=Greatest('modified', 'blog__modified'))
>>> annotated_comment = comments.get()

annotated_comment.last_updated будет самым последним из blog.modified и comment.modified.

Предупреждение

Поведение Greatest при наличии одного или нескольких выражений, которые могут быть null, варьируется в зависимости от базы данных:

  • PostgreSQL: Greatest вернет наибольшее выражение, отличное от NULL, или null если все выражения являются null.
  • SQLite, Oracle и MySQL: Если любое выражение null, Greatest вернет null.

Поведение PostgreSQL можно эмулировать с помощью Coalesce если вы знаете разумное минимальное значение для предоставления в качестве значения по умолчанию.

Least

class Least(*expressions, **extra)

Принимает список из по крайней мере двух имен полей или выражений и возвращает наименьшее значение. Каждый аргумент должен иметь одинаковый тип, поэтому смешивание текста и чисел приведет к ошибке базы данных.

Предупреждение

Поведение Least при наличии одного или нескольких выражений, которые могут быть null варьируется в зависимости от базы данных:

  • PostgreSQL: Least вернет наименьшее выражение, отличное от NULL, или null если все выражения являются null.
  • SQLite, Oracle и MySQL: Если любое выражение null, Least вернет null.

Поведение PostgreSQL можно эмулировать с помощью Coalesce если вы знаете разумное максимальное значение для предоставления в качестве значения по умолчанию.

NullIf

class NullIf(expression1, expression2)

Принимает два выражения и возвращает None если они равны, иначе возвращает expression1.

Примечания по Oracle

Из-за конвенции Oracle, эта функция возвращает пустую строку вместо None когда выражения имеют тип CharField.

Передача Value(None) в expression1 запрещена в Oracle, так как Oracle не принимает NULL в качестве первого аргумента.

Функции даты

В примерах каждой функции мы будем использовать следующую модель:

class Experiment(models.Model):
    start_datetime = models.DateTimeField()
    start_date = models.DateField(null=True, blank=True)
    start_time = models.TimeField(null=True, blank=True)
    end_datetime = models.DateTimeField(null=True, blank=True)
    end_date = models.DateField(null=True, blank=True)
    end_time = models.TimeField(null=True, blank=True)

Extract

class Extract(expression, lookup_name=None, tzinfo=None, **extra)

Извлекает компонент даты в виде числа.

Принимает expression представляющее DateField, DateTimeField, TimeField, или DurationField и lookup_name, и возвращает часть даты, указанную в lookup_name, как IntegerField. Django обычно использует функцию извлечения базы данных, поэтому вы можете использовать любую lookup_name поддерживаемую вашей базой данных. Подкласс tzinfo, обычно предоставляемый pytz, может быть передан для извлечения значения в конкретной часовой зоне.

Для даты-времени 2015-06-15 23:30:01.000321+00:00 встроенные lookup_name возвращают:

  • “year”: 2015
  • “iso_year”: 2015
  • “quarter”: 2
  • “month”: 6
  • “day”: 15
  • “week”: 25
  • “week_day”: 2
  • “iso_week_day”: 1
  • “hour”: 23
  • “minute”: 30
  • “second”: 1

Если в Django активна другая часовая зона, например Australia/Melbourne, то дата-время преобразуется в эту часовую зону перед извлечением значения. Смещение часовой зоны для Мельбурна в дате-времени выше составляет +10:00. Значения, возвращаемые при активации этой часовой зоны, будут такими же, как и выше, за исключением:

  • “day”: 16
  • “week_day”: 3
  • “iso_week_day”: 2
  • “hour”: 9

Значения week_day

Значение week_day lookup_type рассчитывается по-другому, чем в большинстве баз данных и в стандартных функциях Python. Эта функция вернёт 1 для воскресенья, 2 для понедельника и 7 для субботы.

Эквивалентный расчет в Python:

>>> from datetime import datetime
>>> dt = datetime(2015, 6, 15)
>>> (dt.isoweekday() % 7) + 1
2

Значения week

Значение week lookup_type рассчитывается на основе ISO-8601, т.е. неделя начинается с понедельника. Первая неделя года — та, которая содержит четверг года, т.е. первая неделя имеет большинство (четыре или более) своих дней в году. Возвращаемое значение находится в диапазоне от 1 до 52 или 53.

Каждому lookup_name выше соответствует подкласс Extract (перечисленные ниже), который обычно используется вместо более громоздкого эквивалента, например, используйте ExtractYear(...) вместо Extract(..., lookup_name='year').

Пример использования:

>>> from datetime import datetime
>>> from django.db.models.functions import Extract
>>> start = datetime(2015, 6, 15)
>>> end = datetime(2015, 7, 2)
>>> Experiment.objects.create(
...    start_datetime=start, start_date=start.date(),
...    end_datetime=end, end_date=end.date())
>>> # Add the experiment start year as a field in the QuerySet.
>>> experiment = Experiment.objects.annotate(
...    start_year=Extract('start_datetime', 'year')).get()
>>> experiment.start_year
2015
>>> # How many experiments completed in the same year in which they started?
>>> Experiment.objects.filter(
...    start_datetime__year=Extract('end_datetime', 'year')).count()
1

DateField функции извлечения

class ExtractYear(expression, tzinfo=None, **extra)
lookup_name = 'year'
class ExtractIsoYear(expression, tzinfo=None, **extra)

Возвращает год по ISO-8601.

lookup_name = 'iso_year'
class ExtractMonth(expression, tzinfo=None, **extra)
lookup_name = 'month'
class ExtractDay(expression, tzinfo=None, **extra)
lookup_name = 'day'
class ExtractWeekDay(expression, tzinfo=None, **extra)
lookup_name = 'week_day'
class ExtractIsoWeekDay(expression, tzinfo=None, **extra)
Новое в Django 3.1.

Возвращает день недели ISO-8601, где 1 — понедельник, а 7 — воскресенье.

lookup_name = 'iso_week_day'
class ExtractWeek(expression, tzinfo=None, **extra)
lookup_name = 'week'
class ExtractQuarter(expression, tzinfo=None, **extra)
lookup_name = 'quarter'

Эти функции логически эквивалентны Extract('date_field', lookup_name). Каждый класс также является Transform зарегистрированным в DateField и DateTimeField как __(lookup_name), например, __year.

Так как у DateField нет компонента времени, только подклассы Extract, которые работают с частями даты, могут быть использованы с DateField:

>>> from datetime import datetime
>>> from django.utils import timezone
>>> from django.db.models.functions import (
...     ExtractDay, ExtractMonth, ExtractQuarter, ExtractWeek,
...     ExtractIsoWeekDay, ExtractWeekDay, ExtractIsoYear, ExtractYear,
... )
>>> start_2015 = datetime(2015, 6, 15, 23, 30, 1, tzinfo=timezone.utc)
>>> end_2015 = datetime(2015, 6, 16, 13, 11, 27, tzinfo=timezone.utc)
>>> Experiment.objects.create(
...    start_datetime=start_2015, start_date=start_2015.date(),
...    end_datetime=end_2015, end_date=end_2015.date())
>>> Experiment.objects.annotate(
...     year=ExtractYear('start_date'),
...     isoyear=ExtractIsoYear('start_date'),
...     quarter=ExtractQuarter('start_date'),
...     month=ExtractMonth('start_date'),
...     week=ExtractWeek('start_date'),
...     day=ExtractDay('start_date'),
...     weekday=ExtractWeekDay('start_date'),
...     isoweekday=ExtractIsoWeekDay('start_date'),
... ).values(
...     'year', 'isoyear', 'quarter', 'month', 'week', 'day', 'weekday',
...     'isoweekday',
... ).get(end_date__year=ExtractYear('start_date'))
{'year': 2015, 'isoyear': 2015, 'quarter': 2, 'month': 6, 'week': 25,
 'day': 15, 'weekday': 2, 'isoweekday': 1}

DateTimeField функции извлечения

В дополнение к следующему, все функции извлечения для DateField, перечисленные выше, также могут быть использованы с DateTimeField.

class ExtractHour(expression, tzinfo=None, **extra)
lookup_name = 'hour'
class ExtractMinute(expression, tzinfo=None, **extra)
lookup_name = 'minute'
class ExtractSecond(expression, tzinfo=None, **extra)
lookup_name = 'second'

Эти функции логически эквивалентны Extract('datetime_field', lookup_name). Каждый класс также является Transform зарегистрированным в DateTimeField как __(lookup_name), например, __minute.

Примеры DateTimeField:

>>> from datetime import datetime
>>> from django.utils import timezone
>>> from django.db.models.functions import (
...     ExtractDay, ExtractHour, ExtractMinute, ExtractMonth,
...     ExtractQuarter, ExtractSecond, ExtractWeek, ExtractIsoWeekDay,
...     ExtractWeekDay, ExtractIsoYear, ExtractYear,
... )
>>> start_2015 = datetime(2015, 6, 15, 23, 30, 1, tzinfo=timezone.utc)
>>> end_2015 = datetime(2015, 6, 16, 13, 11, 27, tzinfo=timezone.utc)
>>> Experiment.objects.create(
...    start_datetime=start_2015, start_date=start_2015.date(),
...    end_datetime=end_2015, end_date=end_2015.date())
>>> Experiment.objects.annotate(
...     year=ExtractYear('start_datetime'),
...     isoyear=ExtractIsoYear('start_datetime'),
...     quarter=ExtractQuarter('start_datetime'),
...     month=ExtractMonth('start_datetime'),
...     week=ExtractWeek('start_datetime'),
...     day=ExtractDay('start_datetime'),
...     weekday=ExtractWeekDay('start_datetime'),
...     isoweekday=ExtractIsoWeekDay('start_datetime'),
...     hour=ExtractHour('start_datetime'),
...     minute=ExtractMinute('start_datetime'),
...     second=ExtractSecond('start_datetime'),
... ).values(
...     'year', 'isoyear', 'month', 'week', 'day',
...     'weekday', 'isoweekday', 'hour', 'minute', 'second',
... ).get(end_datetime__year=ExtractYear('start_datetime'))
{'year': 2015, 'isoyear': 2015, 'quarter': 2, 'month': 6, 'week': 25,
 'day': 15, 'weekday': 2, 'isoweekday': 1, 'hour': 23, 'minute': 30,
 'second': 1}

Когда USE_TZ равно True, даты и время хранятся в базе данных в формате UTC. Если в Django активен другой часовой пояс, значение даты и времени преобразуется в этот часовой пояс перед извлечением. Приведенный ниже пример преобразует значения в часовой пояс Мельбурна (UTC +10:00), что изменяет значения дня, дня недели и часа, которые возвращаются:

>>> import pytz
>>> melb = pytz.timezone('Australia/Melbourne')  # UTC+10:00
>>> with timezone.override(melb):
...    Experiment.objects.annotate(
...        day=ExtractDay('start_datetime'),
...        weekday=ExtractWeekDay('start_datetime'),
...        isoweekday=ExtractIsoWeekDay('start_datetime'),
...        hour=ExtractHour('start_datetime'),
...    ).values('day', 'weekday', 'isoweekday', 'hour').get(
...        end_datetime__year=ExtractYear('start_datetime'),
...    )
{'day': 16, 'weekday': 3, 'isoweekday': 2, 'hour': 9}

Явное указание часового пояса для функции Extract действует аналогично и имеет приоритет над активным часовым поясом:

>>> import pytz
>>> melb = pytz.timezone('Australia/Melbourne')
>>> Experiment.objects.annotate(
...     day=ExtractDay('start_datetime', tzinfo=melb),
...     weekday=ExtractWeekDay('start_datetime', tzinfo=melb),
...     isoweekday=ExtractIsoWeekDay('start_datetime', tzinfo=melb),
...     hour=ExtractHour('start_datetime', tzinfo=melb),
... ).values('day', 'weekday', 'isoweekday', 'hour').get(
...     end_datetime__year=ExtractYear('start_datetime'),
... )
{'day': 16, 'weekday': 3, 'isoweekday': 2, 'hour': 9}

Now

class Now

Возвращает текущую дату и время сервера базы данных во время выполнения запроса, обычно используя SQL CURRENT_TIMESTAMP.

Пример использования:

>>> from django.db.models.functions import Now
>>> Article.objects.filter(published__lte=Now())
<QuerySet [<Article: How to Django>]>

Уточнения по PostgreSQL

В PostgreSQL SQL CURRENT_TIMESTAMP возвращает время начала текущей транзакции. Поэтому для межбазовой совместимости Now() использует STATEMENT_TIMESTAMP вместо этого. Если вам нужен отметка времени транзакции, используйте django.contrib.postgres.functions.TransactionNow.

Trunc

class Trunc(expression, kind, output_field=None, tzinfo=None, is_dst=None, **extra)

Обрезает дату до значимого компонента.

Если вам нужно только узнать, произошло ли событие в определённом году, часе или дне, но не точное значение секунды, то Trunc (и его подклассы) могут быть полезны для фильтрации или агрегирования данных. Например, вы можете использовать Trunc для расчёта количества продаж в день.

Trunc принимает один expression, представляющий DateField, TimeField, или DateTimeField, kind представляющий часть даты или времени, и output_field значение, которое равно DateTimeField(), TimeField(), или DateField(). Он возвращает дату и время, дату или время в зависимости от output_field, с полями до kind установлеными в минимальное значение. Если output_field опущен, по умолчанию используется output_field expression. Подкласс tzinfo, обычно предоставляемый pytz, может быть передан для обрезки значения в определённом часовом поясе.

Параметр is_dst указывает, следует ли pytz интерпретировать несуществующие или неоднозначные даты и время в летнее время. По умолчанию (когда is_dst=None), pytz вызывает исключение для таких дат и времени.

Добавлено в Django 3.0:

Был добавлен параметр is_dst.

Для даты и времени 2015-06-15 14:30:50.000321+00:00, встроенные kind возвращают:

  • “год”: 2015-01-01 00:00:00+00:00
  • “квартал”: 2015-04-01 00:00:00+00:00
  • “месяц”: 2015-06-01 00:00:00+00:00
  • “неделя”: 2015-06-15 00:00:00+00:00
  • “день”: 2015-06-15 00:00:00+00:00
  • “час”: 2015-06-15 14:00:00+00:00
  • “минута”: 2015-06-15 14:30:00+00:00
  • “секунда”: 2015-06-15 14:30:50+00:00

Если в Django активен другой часовой пояс, например, Australia/Melbourne, дата и время преобразуются в новый часовой пояс перед обрезкой. Смещение часового пояса Мельбурна в примере даты выше составляет +10:00. Возвращаемые значения при активном часовом поясе будут:

  • “год”: 2015-01-01 00:00:00+11:00
  • “квартал”: 2015-04-01 00:00:00+10:00
  • “месяц”: 2015-06-01 00:00:00+10:00
  • “неделя”: 2015-06-16 00:00:00+10:00
  • “день”: 2015-06-16 00:00:00+10:00
  • “час”: 2015-06-16 00:00:00+10:00
  • “минута”: 2015-06-16 00:30:00+10:00
  • “секунда”: 2015-06-16 00:30:50+10:00

Год имеет смещение +11:00, так как результат перешёл в летнее время.

У каждого kind выше есть соответствующий подкласс Trunc (перечисленные ниже), который обычно следует использовать вместо более громоздкого эквивалента, например, используйте TruncYear(...) вместо Trunc(..., kind='year').

Все подклассы определены как преобразования, но не зарегистрированы с какими-либо полями, потому что имена поиска уже зарезервированы подклассами Extract.

Пример использования:

>>> from datetime import datetime
>>> from django.db.models import Count, DateTimeField
>>> from django.db.models.functions import Trunc
>>> Experiment.objects.create(start_datetime=datetime(2015, 6, 15, 14, 30, 50, 321))
>>> Experiment.objects.create(start_datetime=datetime(2015, 6, 15, 14, 40, 2, 123))
>>> Experiment.objects.create(start_datetime=datetime(2015, 12, 25, 10, 5, 27, 999))
>>> experiments_per_day = Experiment.objects.annotate(
...    start_day=Trunc('start_datetime', 'day', output_field=DateTimeField())
... ).values('start_day').annotate(experiments=Count('id'))
>>> for exp in experiments_per_day:
...     print(exp['start_day'], exp['experiments'])
...
2015-06-15 00:00:00 2
2015-12-25 00:00:00 1
>>> experiments = Experiment.objects.annotate(
...    start_day=Trunc('start_datetime', 'day', output_field=DateTimeField())
... ).filter(start_day=datetime(2015, 6, 15))
>>> for exp in experiments:
...     print(exp.start_datetime)
...
2015-06-15 14:30:50.000321
2015-06-15 14:40:02.000123

DateField обрезка

class TruncYear(expression, output_field=None, tzinfo=None, is_dst=None, **extra)
kind = 'year'
class TruncMonth(expression, output_field=None, tzinfo=None, is_dst=None, **extra)
kind = 'month'
class TruncWeek(expression, output_field=None, tzinfo=None, is_dst=None, **extra)

Обрезает до полуночи в понедельник недели.

kind = 'week'
class TruncQuarter(expression, output_field=None, tzinfo=None, is_dst=None, **extra)
kind = 'quarter'

Эти логически эквивалентны Trunc('date_field', kind). Они обрезают все части даты до kind, что позволяет группировать или фильтровать даты с меньшей точностью. expression может иметь output_field либо DateField, либо DateTimeField.

Поскольку DateField не имеют компонента времени, только подклассы Trunc , которые обрабатывают части даты, могут быть использованы с DateField:

>>> from datetime import datetime
>>> from django.db.models import Count
>>> from django.db.models.functions import TruncMonth, TruncYear
>>> from django.utils import timezone
>>> start1 = datetime(2014, 6, 15, 14, 30, 50, 321, tzinfo=timezone.utc)
>>> start2 = datetime(2015, 6, 15, 14, 40, 2, 123, tzinfo=timezone.utc)
>>> start3 = datetime(2015, 12, 31, 17, 5, 27, 999, tzinfo=timezone.utc)
>>> Experiment.objects.create(start_datetime=start1, start_date=start1.date())
>>> Experiment.objects.create(start_datetime=start2, start_date=start2.date())
>>> Experiment.objects.create(start_datetime=start3, start_date=start3.date())
>>> experiments_per_year = Experiment.objects.annotate(
...    year=TruncYear('start_date')).values('year').annotate(
...    experiments=Count('id'))
>>> for exp in experiments_per_year:
...     print(exp['year'], exp['experiments'])
...
2014-01-01 1
2015-01-01 2

>>> import pytz
>>> melb = pytz.timezone('Australia/Melbourne')
>>> experiments_per_month = Experiment.objects.annotate(
...    month=TruncMonth('start_datetime', tzinfo=melb)).values('month').annotate(
...    experiments=Count('id'))
>>> for exp in experiments_per_month:
...     print(exp['month'], exp['experiments'])
...
2015-06-01 00:00:00+10:00 1
2016-01-01 00:00:00+11:00 1
2014-06-01 00:00:00+10:00 1

DateTimeField обрезка

class TruncDate(expression, **extra)
lookup_name = 'date'
output_field = DateField()

TruncDate преобразует expression в дату, а не используя встроенную SQL функцию обрезки. Он также зарегистрирован как преобразование для DateTimeField как __date.

class TruncTime(expression, **extra)
lookup_name = 'time'
output_field = TimeField()

TruncTime преобразует expression в время, а не используя встроенную SQL функцию обрезки. Он также зарегистрирован как преобразование для DateTimeField как __time.

class TruncDay(expression, output_field=None, tzinfo=None, is_dst=None, **extra)
kind = 'day'
class TruncHour(expression, output_field=None, tzinfo=None, is_dst=None, **extra)
kind = 'hour'
class TruncMinute(expression, output_field=None, tzinfo=None, is_dst=None, **extra)
kind = 'minute'
class TruncSecond(expression, output_field=None, tzinfo=None, is_dst=None, **extra)
kind = 'second'

Эти логически эквивалентны Trunc('datetime_field', kind). Они обрезают все части даты до kind и позволяют группировать или фильтровать даты и время с меньшей точностью. expression должен иметь output_field значение DateTimeField.

Пример использования:

>>> from datetime import date, datetime
>>> from django.db.models import Count
>>> from django.db.models.functions import (
...     TruncDate, TruncDay, TruncHour, TruncMinute, TruncSecond,
... )
>>> from django.utils import timezone
>>> import pytz
>>> start1 = datetime(2014, 6, 15, 14, 30, 50, 321, tzinfo=timezone.utc)
>>> Experiment.objects.create(start_datetime=start1, start_date=start1.date())
>>> melb = pytz.timezone('Australia/Melbourne')
>>> Experiment.objects.annotate(
...     date=TruncDate('start_datetime'),
...     day=TruncDay('start_datetime', tzinfo=melb),
...     hour=TruncHour('start_datetime', tzinfo=melb),
...     minute=TruncMinute('start_datetime'),
...     second=TruncSecond('start_datetime'),
... ).values('date', 'day', 'hour', 'minute', 'second').get()
{'date': datetime.date(2014, 6, 15),
 'day': datetime.datetime(2014, 6, 16, 0, 0, tzinfo=<DstTzInfo 'Australia/Melbourne' AEST+10:00:00 STD>),
 'hour': datetime.datetime(2014, 6, 16, 0, 0, tzinfo=<DstTzInfo 'Australia/Melbourne' AEST+10:00:00 STD>),
 'minute': 'minute': datetime.datetime(2014, 6, 15, 14, 30, tzinfo=<UTC>),
 'second': datetime.datetime(2014, 6, 15, 14, 30, 50, tzinfo=<UTC>)
}

TimeField обрезка

class TruncHour(expression, output_field=None, tzinfo=None, is_dst=None, **extra)
kind = 'hour'
class TruncMinute(expression, output_field=None, tzinfo=None, is_dst=None, **extra)
kind = 'minute'
class TruncSecond(expression, output_field=None, tzinfo=None, is_dst=None, **extra)
kind = 'second'

Эти логически эквивалентны Trunc('time_field', kind). Они обрезают все части времени до kind, что позволяет группировать или фильтровать время с меньшей точностью. expression может иметь output_field значение TimeField или DateTimeField.

Поскольку TimeField не имеют компонента даты, только подклассы Trunc , которые обрабатывают части времени, могут быть использованы с TimeField:

>>> from datetime import datetime
>>> from django.db.models import Count, TimeField
>>> from django.db.models.functions import TruncHour
>>> from django.utils import timezone
>>> start1 = datetime(2014, 6, 15, 14, 30, 50, 321, tzinfo=timezone.utc)
>>> start2 = datetime(2014, 6, 15, 14, 40, 2, 123, tzinfo=timezone.utc)
>>> start3 = datetime(2015, 12, 31, 17, 5, 27, 999, tzinfo=timezone.utc)
>>> Experiment.objects.create(start_datetime=start1, start_time=start1.time())
>>> Experiment.objects.create(start_datetime=start2, start_time=start2.time())
>>> Experiment.objects.create(start_datetime=start3, start_time=start3.time())
>>> experiments_per_hour = Experiment.objects.annotate(
...    hour=TruncHour('start_datetime', output_field=TimeField()),
... ).values('hour').annotate(experiments=Count('id'))
>>> for exp in experiments_per_hour:
...     print(exp['hour'], exp['experiments'])
...
14:00:00 2
17:00:00 1

>>> import pytz
>>> melb = pytz.timezone('Australia/Melbourne')
>>> experiments_per_hour = Experiment.objects.annotate(
...    hour=TruncHour('start_datetime', tzinfo=melb),
... ).values('hour').annotate(experiments=Count('id'))
>>> for exp in experiments_per_hour:
...     print(exp['hour'], exp['experiments'])
...
2014-06-16 00:00:00+10:00 2
2016-01-01 04:00:00+11:00 1

Функции математики

В примерах функций математики мы будем использовать следующую модель:

class Vector(models.Model):
    x = models.FloatField()
    y = models.FloatField()

Abs

class Abs(expression, **extra)

Возвращает абсолютное значение числового поля или выражения.

Пример использования:

>>> from django.db.models.functions import Abs
>>> Vector.objects.create(x=-0.5, y=1.1)
>>> vector = Vector.objects.annotate(x_abs=Abs('x'), y_abs=Abs('y')).get()
>>> vector.x_abs, vector.y_abs
(0.5, 1.1)

Он также может быть зарегистрирован как преобразование. Например:

>>> from django.db.models import FloatField
>>> from django.db.models.functions import Abs
>>> FloatField.register_lookup(Abs)
>>> # Get vectors inside the unit cube
>>> vectors = Vector.objects.filter(x__abs__lt=1, y__abs__lt=1)

ACos

class ACos(expression, **extra)

Возвращает арккосинус числового поля или выражения. Значение выражения должно быть в диапазоне от -1 до 1.

Пример использования:

>>> from django.db.models.functions import ACos
>>> Vector.objects.create(x=0.5, y=-0.9)
>>> vector = Vector.objects.annotate(x_acos=ACos('x'), y_acos=ACos('y')).get()
>>> vector.x_acos, vector.y_acos
(1.0471975511965979, 2.6905658417935308)

Он также может быть зарегистрирован как преобразование. Например:

>>> from django.db.models import FloatField
>>> from django.db.models.functions import ACos
>>> FloatField.register_lookup(ACos)
>>> # Get vectors whose arccosine is less than 1
>>> vectors = Vector.objects.filter(x__acos__lt=1, y__acos__lt=1)

ASin

class ASin(expression, **extra)

Возвращает арксинус числового поля или выражения. Значение выражения должно быть в диапазоне от -1 до 1.

Пример использования:

>>> from django.db.models.functions import ASin
>>> Vector.objects.create(x=0, y=1)
>>> vector = Vector.objects.annotate(x_asin=ASin('x'), y_asin=ASin('y')).get()
>>> vector.x_asin, vector.y_asin
(0.0, 1.5707963267948966)

Он также может быть зарегистрирован как преобразование. Например:

>>> from django.db.models import FloatField
>>> from django.db.models.functions import ASin
>>> FloatField.register_lookup(ASin)
>>> # Get vectors whose arcsine is less than 1
>>> vectors = Vector.objects.filter(x__asin__lt=1, y__asin__lt=1)

ATan

class ATan(expression, **extra)

Возвращает арктангенс числового поля или выражения.

Пример использования:

>>> from django.db.models.functions import ATan
>>> Vector.objects.create(x=3.12, y=6.987)
>>> vector = Vector.objects.annotate(x_atan=ATan('x'), y_atan=ATan('y')).get()
>>> vector.x_atan, vector.y_atan
(1.2606282660069106, 1.428638798133829)

Он также может быть зарегистрирован как преобразование. Например:

>>> from django.db.models import FloatField
>>> from django.db.models.functions import ATan
>>> FloatField.register_lookup(ATan)
>>> # Get vectors whose arctangent is less than 2
>>> vectors = Vector.objects.filter(x__atan__lt=2, y__atan__lt=2)

ATan2

class ATan2(expression1, expression2, **extra)

Возвращает арктангенс expression1 / expression2.

Пример использования:

>>> from django.db.models.functions import ATan2
>>> Vector.objects.create(x=2.5, y=1.9)
>>> vector = Vector.objects.annotate(atan2=ATan2('x', 'y')).get()
>>> vector.atan2
0.9209258773829491

Ceil

class Ceil(expression, **extra)

Возвращает наименьшее целое число, большее или равное числовому полю или выражению.

Пример использования:

>>> from django.db.models.functions import Ceil
>>> Vector.objects.create(x=3.12, y=7.0)
>>> vector = Vector.objects.annotate(x_ceil=Ceil('x'), y_ceil=Ceil('y')).get()
>>> vector.x_ceil, vector.y_ceil
(4.0, 7.0)

Его также можно зарегистрировать как преобразование. Например:

>>> from django.db.models import FloatField
>>> from django.db.models.functions import Ceil
>>> FloatField.register_lookup(Ceil)
>>> # Get vectors whose ceil is less than 10
>>> vectors = Vector.objects.filter(x__ceil__lt=10, y__ceil__lt=10)

Cos

class Cos(expression, **extra)

Возвращает косинус числового поля или выражения.

Пример использования:

>>> from django.db.models.functions import Cos
>>> Vector.objects.create(x=-8.0, y=3.1415926)
>>> vector = Vector.objects.annotate(x_cos=Cos('x'), y_cos=Cos('y')).get()
>>> vector.x_cos, vector.y_cos
(-0.14550003380861354, -0.9999999999999986)

Его также можно зарегистрировать как преобразование. Например:

>>> from django.db.models import FloatField
>>> from django.db.models.functions import Cos
>>> FloatField.register_lookup(Cos)
>>> # Get vectors whose cosine is less than 0.5
>>> vectors = Vector.objects.filter(x__cos__lt=0.5, y__cos__lt=0.5)

Cot

class Cot(expression, **extra)

Возвращает котангенс числового поля или выражения.

Пример использования:

>>> from django.db.models.functions import Cot
>>> Vector.objects.create(x=12.0, y=1.0)
>>> vector = Vector.objects.annotate(x_cot=Cot('x'), y_cot=Cot('y')).get()
>>> vector.x_cot, vector.y_cot
(-1.5726734063976826, 0.642092615934331)

Его также можно зарегистрировать как преобразование. Например:

>>> from django.db.models import FloatField
>>> from django.db.models.functions import Cot
>>> FloatField.register_lookup(Cot)
>>> # Get vectors whose cotangent is less than 1
>>> vectors = Vector.objects.filter(x__cot__lt=1, y__cot__lt=1)

Degrees

class Degrees(expression, **extra)

Преобразует числовое поле или выражение из радиан в градусы.

Пример использования:

>>> from django.db.models.functions import Degrees
>>> Vector.objects.create(x=-1.57, y=3.14)
>>> vector = Vector.objects.annotate(x_d=Degrees('x'), y_d=Degrees('y')).get()
>>> vector.x_d, vector.y_d
(-89.95437383553924, 179.9087476710785)

Его также можно зарегистрировать как преобразование. Например:

>>> from django.db.models import FloatField
>>> from django.db.models.functions import Degrees
>>> FloatField.register_lookup(Degrees)
>>> # Get vectors whose degrees are less than 360
>>> vectors = Vector.objects.filter(x__degrees__lt=360, y__degrees__lt=360)

Exp

class Exp(expression, **extra)

Возвращает значение e (натуральный логарифм) в степени числового поля или выражения.

Пример использования:

>>> from django.db.models.functions import Exp
>>> Vector.objects.create(x=5.4, y=-2.0)
>>> vector = Vector.objects.annotate(x_exp=Exp('x'), y_exp=Exp('y')).get()
>>> vector.x_exp, vector.y_exp
(221.40641620418717, 0.1353352832366127)

Его также можно зарегистрировать как преобразование. Например:

>>> from django.db.models import FloatField
>>> from django.db.models.functions import Exp
>>> FloatField.register_lookup(Exp)
>>> # Get vectors whose exp() is greater than 10
>>> vectors = Vector.objects.filter(x__exp__gt=10, y__exp__gt=10)

Floor

class Floor(expression, **extra)

Возвращает наибольшее целое число, не большее чем числовое поле или выражение.

Пример использования:

>>> from django.db.models.functions import Floor
>>> Vector.objects.create(x=5.4, y=-2.3)
>>> vector = Vector.objects.annotate(x_floor=Floor('x'), y_floor=Floor('y')).get()
>>> vector.x_floor, vector.y_floor
(5.0, -3.0)

Его также можно зарегистрировать как преобразование. Например:

>>> from django.db.models import FloatField
>>> from django.db.models.functions import Floor
>>> FloatField.register_lookup(Floor)
>>> # Get vectors whose floor() is greater than 10
>>> vectors = Vector.objects.filter(x__floor__gt=10, y__floor__gt=10)

Ln

class Ln(expression, **extra)

Возвращает натуральный логарифм числового поля или выражения.

Пример использования:

>>> from django.db.models.functions import Ln
>>> Vector.objects.create(x=5.4, y=233.0)
>>> vector = Vector.objects.annotate(x_ln=Ln('x'), y_ln=Ln('y')).get()
>>> vector.x_ln, vector.y_ln
(1.6863989535702288, 5.4510384535657)

Его также можно зарегистрировать как преобразование. Например:

>>> from django.db.models import FloatField
>>> from django.db.models.functions import Ln
>>> FloatField.register_lookup(Ln)
>>> # Get vectors whose value greater than e
>>> vectors = Vector.objects.filter(x__ln__gt=1, y__ln__gt=1)

Log

class Log(expression1, expression2, **extra)

Принимает два числовых поля или выражения и возвращает логарифм первого по основанию второго.

Пример использования:

>>> from django.db.models.functions import Log
>>> Vector.objects.create(x=2.0, y=4.0)
>>> vector = Vector.objects.annotate(log=Log('x', 'y')).get()
>>> vector.log
2.0

Mod

class Mod(expression1, expression2, **extra)

Принимает два числовых поля или выражения и возвращает остаток от деления первого на второе (операция modulo).

Пример использования:

>>> from django.db.models.functions import Mod
>>> Vector.objects.create(x=5.4, y=2.3)
>>> vector = Vector.objects.annotate(mod=Mod('x', 'y')).get()
>>> vector.mod
0.8

Pi

class Pi(**extra)

Возвращает значение математической константы π.

Power

class Power(expression1, expression2, **extra)

Принимает два числовых поля или выражения и возвращает значение первого в степени второго.

Пример использования:

>>> from django.db.models.functions import Power
>>> Vector.objects.create(x=2, y=-2)
>>> vector = Vector.objects.annotate(power=Power('x', 'y')).get()
>>> vector.power
0.25

Radians

class Radians(expression, **extra)

Преобразует числовое поле или выражение из градусов в радианы.

Пример использования:

>>> from django.db.models.functions import Radians
>>> Vector.objects.create(x=-90, y=180)
>>> vector = Vector.objects.annotate(x_r=Radians('x'), y_r=Radians('y')).get()
>>> vector.x_r, vector.y_r
(-1.5707963267948966, 3.141592653589793)

Его также можно зарегистрировать как преобразование. Например:

>>> from django.db.models import FloatField
>>> from django.db.models.functions import Radians
>>> FloatField.register_lookup(Radians)
>>> # Get vectors whose radians are less than 1
>>> vectors = Vector.objects.filter(x__radians__lt=1, y__radians__lt=1)

Round

class Round(expression, **extra)

Округляет числовое поле или выражение до ближайшего целого числа. Способ округления половинок зависит от базы данных.

Пример использования:

>>> from django.db.models.functions import Round
>>> Vector.objects.create(x=5.4, y=-2.3)
>>> vector = Vector.objects.annotate(x_r=Round('x'), y_r=Round('y')).get()
>>> vector.x_r, vector.y_r
(5.0, -2.0)

Его также можно зарегистрировать как преобразование. Например:

>>> from django.db.models import FloatField
>>> from django.db.models.functions import Round
>>> FloatField.register_lookup(Round)
>>> # Get vectors whose round() is less than 20
>>> vectors = Vector.objects.filter(x__round__lt=20, y__round__lt=20)

Sign

class Sign(expression, **extra)
Новое в Django 3.0.

Возвращает знак (-1, 0, 1) числового поля или выражения.

Пример использования:

>>> from django.db.models.functions import Sign
>>> Vector.objects.create(x=5.4, y=-2.3)
>>> vector = Vector.objects.annotate(x_sign=Sign('x'), y_sign=Sign('y')).get()
>>> vector.x_sign, vector.y_sign
(1, -1)

Его также можно зарегистрировать как преобразование. Например:

>>> from django.db.models import FloatField
>>> from django.db.models.functions import Sign
>>> FloatField.register_lookup(Sign)
>>> # Get vectors whose signs of components are less than 0.
>>> vectors = Vector.objects.filter(x__sign__lt=0, y__sign__lt=0)

Sin

class Sin(expression, **extra)

Возвращает синус числового поля или выражения.

Пример использования:

>>> from django.db.models.functions import Sin
>>> Vector.objects.create(x=5.4, y=-2.3)
>>> vector = Vector.objects.annotate(x_sin=Sin('x'), y_sin=Sin('y')).get()
>>> vector.x_sin, vector.y_sin
(-0.7727644875559871, -0.7457052121767203)

Его также можно зарегистрировать как преобразование. Например:

>>> from django.db.models import FloatField
>>> from django.db.models.functions import Sin
>>> FloatField.register_lookup(Sin)
>>> # Get vectors whose sin() is less than 0
>>> vectors = Vector.objects.filter(x__sin__lt=0, y__sin__lt=0)

Sqrt

class Sqrt(expression, **extra)

Возвращает квадратный корень из неотрицательного числового поля или выражения.

Пример использования:

>>> from django.db.models.functions import Sqrt
>>> Vector.objects.create(x=4.0, y=12.0)
>>> vector = Vector.objects.annotate(x_sqrt=Sqrt('x'), y_sqrt=Sqrt('y')).get()
>>> vector.x_sqrt, vector.y_sqrt
(2.0, 3.46410)

Его также можно зарегистрировать как преобразование. Например:

>>> from django.db.models import FloatField
>>> from django.db.models.functions import Sqrt
>>> FloatField.register_lookup(Sqrt)
>>> # Get vectors whose sqrt() is less than 5
>>> vectors = Vector.objects.filter(x__sqrt__lt=5, y__sqrt__lt=5)

Tan

class Tan(expression, **extra)

Возвращает тангенс числового поля или выражения.

Пример использования:

>>> from django.db.models.functions import Tan
>>> Vector.objects.create(x=0, y=12)
>>> vector = Vector.objects.annotate(x_tan=Tan('x'), y_tan=Tan('y')).get()
>>> vector.x_tan, vector.y_tan
(0.0, -0.6358599286615808)

Его также можно зарегистрировать как преобразование. Например:

>>> from django.db.models import FloatField
>>> from django.db.models.functions import Tan
>>> FloatField.register_lookup(Tan)
>>> # Get vectors whose tangent is less than 0
>>> vectors = Vector.objects.filter(x__tan__lt=0, y__tan__lt=0)

Функции текста

Chr

class Chr(expression, **extra)

Принимает числовое поле или выражение и возвращает текстовое представление выражения как одиночного символа. Работает аналогично функции Python’s chr().

Как и Length, его можно зарегистрировать как преобразование на IntegerField. Имя по умолчанию для поиска - chr.

Пример использования:

>>> from django.db.models.functions import Chr
>>> Author.objects.create(name='Margaret Smith')
>>> author = Author.objects.filter(name__startswith=Chr(ord('M'))).get()
>>> print(author.name)
Margaret Smith

Concat

class Concat(*expressions, **extra)

Принимает список из как минимум двух текстовых полей или выражений и возвращает конкатенированный текст. Каждый аргумент должен быть текстового или символьного типа. Если вы хотите конкатенировать TextField() с CharField(), убедитесь, что вы сообщили Django, что output_field должен быть TextField(). Указание output_field также необходимо при конкатенации Value, как показано в примере ниже.

Эта функция никогда не вернёт значение null. В тех базах данных, где нулевой аргумент приводит к null всему выражению, Django гарантирует, что каждый нулевой фрагмент преобразуется в пустую строку предварительно.

Пример использования:

>>> # Get the display name as "name (goes_by)"
>>> from django.db.models import CharField, Value as V
>>> from django.db.models.functions import Concat
>>> Author.objects.create(name='Margaret Smith', goes_by='Maggie')
>>> author = Author.objects.annotate(
...     screen_name=Concat(
...         'name', V(' ('), 'goes_by', V(')'),
...         output_field=CharField()
...     )
... ).get()
>>> print(author.screen_name)
Margaret Smith (Maggie)

Left

class Left(expression, length, **extra)

Возвращает первые length символов данного текстового поля или выражения.

Пример использования:

>>> from django.db.models.functions import Left
>>> Author.objects.create(name='Margaret Smith')
>>> author = Author.objects.annotate(first_initial=Left('name', 1)).get()
>>> print(author.first_initial)
M

Length

class Length(expression, **extra)

Принимает единственное текстовое поле или выражение и возвращает количество символов значения. Если выражение null, то длина также будет null.

Пример использования:

>>> # Get the length of the name and goes_by fields
>>> from django.db.models.functions import Length
>>> Author.objects.create(name='Margaret Smith')
>>> author = Author.objects.annotate(
...    name_length=Length('name'),
...    goes_by_length=Length('goes_by')).get()
>>> print(author.name_length, author.goes_by_length)
(14, None)

Его также можно зарегистрировать как преобразование. Например:

>>> from django.db.models import CharField
>>> from django.db.models.functions import Length
>>> CharField.register_lookup(Length)
>>> # Get authors whose name is longer than 7 characters
>>> authors = Author.objects.filter(name__length__gt=7)

Lower

class Lower(expression, **extra)

Принимает единственное текстовое поле или выражение и возвращает строчное представление.

Его также можно зарегистрировать как преобразование, как описано в Length.

Пример использования:

>>> from django.db.models.functions import Lower
>>> Author.objects.create(name='Margaret Smith')
>>> author = Author.objects.annotate(name_lower=Lower('name')).get()
>>> print(author.name_lower)
margaret smith

LPad

class LPad(expression, length, fill_text=Value(' '), **extra)

Возвращает значение данного текстового поля или выражения, дополненного слева символом fill_text, так чтобы результирующее значение имело длину length символов. Символ по умолчанию fill_text - пробел.

Пример использования:

>>> from django.db.models import Value
>>> from django.db.models.functions import LPad
>>> Author.objects.create(name='John', alias='j')
>>> Author.objects.update(name=LPad('name', 8, Value('abc')))
1
>>> print(Author.objects.get(alias='j').name)
abcaJohn

LTrim

class LTrim(expression, **extra)

Аналогично Trim, но удаляет только ведущие пробелы.

MD5

class MD5(expression, **extra)
Новое в Django 3.0.

Принимает единственное текстовое поле или выражение и возвращает хэш MD5 строки.

Его также можно зарегистрировать как преобразование, как описано в Length.

Пример использования:

>>> from django.db.models.functions import MD5
>>> Author.objects.create(name='Margaret Smith')
>>> author = Author.objects.annotate(name_md5=MD5('name')).get()
>>> print(author.name_md5)
749fb689816b2db85f5b169c2055b247

Ord

class Ord(expression, **extra)

Принимает единственное текстовое поле или выражение и возвращает значение кода Unicode для первого символа этого выражения. Работает аналогично функции Python’s ord(), но исключение не генерируется, если выражение длиннее одного символа.

Его также можно зарегистрировать как преобразование, как описано в Length. Имя по умолчанию для поиска - ord.

Пример использования:

>>> from django.db.models.functions import Ord
>>> Author.objects.create(name='Margaret Smith')
>>> author = Author.objects.annotate(name_code_point=Ord('name')).get()
>>> print(author.name_code_point)
77

Repeat

class Repeat(expression, number, **extra)

Возвращает значение данного текстового поля или выражения, повторенное number раз.

Пример использования:

>>> from django.db.models.functions import Repeat
>>> Author.objects.create(name='John', alias='j')
>>> Author.objects.update(name=Repeat('name', 3))
1
>>> print(Author.objects.get(alias='j').name)
JohnJohnJohn

Replace

class Replace(expression, text, replacement=Value(''), **extra)

Заменяет все вхождения text на replacement в expression . Текст по умолчанию для замены - пустая строка. Аргументы функции регистрозависимые.

Пример использования:

>>> from django.db.models import Value
>>> from django.db.models.functions import Replace
>>> Author.objects.create(name='Margaret Johnson')
>>> Author.objects.create(name='Margaret Smith')
>>> Author.objects.update(name=Replace('name', Value('Margaret'), Value('Margareth')))
2
>>> Author.objects.values('name')
<QuerySet [{'name': 'Margareth Johnson'}, {'name': 'Margareth Smith'}]>

Reverse

class Reverse(expression, **extra)

Принимает одно текстовое поле или выражение и возвращает символы этого выражения в обратном порядке.

Его также можно зарегистрировать в качестве преобразования, как описано в Length. Имя по умолчанию для поиска — reverse.

Пример использования:

>>> from django.db.models.functions import Reverse
>>> Author.objects.create(name='Margaret Smith')
>>> author = Author.objects.annotate(backward=Reverse('name')).get()
>>> print(author.backward)
htimS teragraM

Right

class Right(expression, length, **extra)

Возвращает последние length символы заданного текстового поля или выражения.

Пример использования:

>>> from django.db.models.functions import Right
>>> Author.objects.create(name='Margaret Smith')
>>> author = Author.objects.annotate(last_letter=Right('name', 1)).get()
>>> print(author.last_letter)
h

RPad

class RPad(expression, length, fill_text=Value(' '), **extra)

Аналогично LPad, но дополняет справа.

RTrim

class RTrim(expression, **extra)

Аналогично Trim, но удаляет только пробелы в конце.

SHA1, SHA224, SHA256, SHA384, и SHA512

class SHA1(expression, **extra)
class SHA224(expression, **extra)
class SHA256(expression, **extra)
class SHA384(expression, **extra)
class SHA512(expression, **extra)
Новое в Django 3.0.

Принимает одно текстовое поле или выражение и возвращает определенный хэш строки.

Они также могут быть зарегистрированы как преобразования, как описано в Length.

Пример использования:

>>> from django.db.models.functions import SHA1
>>> Author.objects.create(name='Margaret Smith')
>>> author = Author.objects.annotate(name_sha1=SHA1('name')).get()
>>> print(author.name_sha1)
b87efd8a6c991c390be5a68e8a7945a7851c7e5c

PostgreSQL

Должен быть установлен расширение pgcrypto. Вы можете использовать операцию миграции CryptoExtension для её установки.

Oracle

Oracle не поддерживает функцию SHA224.

StrIndex

class StrIndex(string, substring, **extra)

Возвращает положительное целое число, соответствующее 1-индексированной позиции первого вхождения substring внутри string, или 0, если substring не найдено.

Пример использования:

>>> from django.db.models import Value as V
>>> from django.db.models.functions import StrIndex
>>> Author.objects.create(name='Margaret Smith')
>>> Author.objects.create(name='Smith, Margaret')
>>> Author.objects.create(name='Margaret Jackson')
>>> Author.objects.filter(name='Margaret Jackson').annotate(
...     smith_index=StrIndex('name', V('Smith'))
... ).get().smith_index
0
>>> authors = Author.objects.annotate(
...    smith_index=StrIndex('name', V('Smith'))
... ).filter(smith_index__gt=0)
<QuerySet [<Author: Margaret Smith>, <Author: Smith, Margaret>]>

Предупреждение

В MySQL кодировка таблицы базы данных сопоставление определяет, являются ли сравнения строк (такие как expression и substring этой функции) чувствительными к регистру. Сравнения по умолчанию регистронезависимые.

Substr

class Substr(expression, pos, length=None, **extra)

Возвращает подстроку длиной length из поля или выражения, начиная с позиции pos. Позиция индексируется с 1, поэтому позиция должна быть больше 0. Если length равно None, возвращается остальная часть строки.

Пример использования:

>>> # Set the alias to the first 5 characters of the name as lowercase
>>> from django.db.models.functions import Lower, Substr
>>> Author.objects.create(name='Margaret Smith')
>>> Author.objects.update(alias=Lower(Substr('name', 1, 5)))
1
>>> print(Author.objects.get(name='Margaret Smith').alias)
marga

Trim

class Trim(expression, **extra)

Возвращает значение заданного текстового поля или выражения с удаленными начальными и конечными пробелами.

Пример использования:

>>> from django.db.models.functions import Trim
>>> Author.objects.create(name='  John  ', alias='j')
>>> Author.objects.update(name=Trim('name'))
1
>>> print(Author.objects.get(alias='j').name)
John

Upper

class Upper(expression, **extra)

Принимает одно текстовое поле или выражение и возвращает его представление в верхнем регистре.

Его также можно зарегистрировать в качестве преобразования, как описано в Length.

Пример использования:

>>> from django.db.models.functions import Upper
>>> Author.objects.create(name='Margaret Smith')
>>> author = Author.objects.annotate(name_upper=Upper('name')).get()
>>> print(author.name_upper)
MARGARET SMITH

Функции окон

Существует ряд функций для использования в выражении Window для вычисления ранга элементов или Ntile некоторых строк.

CumeDist

class CumeDist(*expressions, **extra)

Вычисляет кумулятивное распределение значения внутри окна или раздела. Кумулятивное распределение определяется как количество строк, предшествующих или равных текущей строке, деленное на общее количество строк в фрейме.

DenseRank

class DenseRank(*expressions, **extra)

Эквивалентно Rank, но без пробелов.

FirstValue

class FirstValue(expression, **extra)

Возвращает значение, вычисленное в строке, являющейся первой строкой фрейма окна, или None , если такой строки нет.

Lag

class Lag(expression, offset=1, default=None, **extra)

Вычисляет значение, сдвинутое на offset, и если такой строки нет, возвращает default.

default должно иметь тот же тип, что и expression, однако это проверяется только базой данных, а не в Python.

MariaDB и default

MariaDB не поддерживает параметр default.

LastValue

class LastValue(expression, **extra)

Аналогично FirstValue, вычисляет последнее значение в данном фрагменте.

Lead

class Lead(expression, offset=1, default=None, **extra)

Вычисляет ведущее значение в данном фрейме. Оба offset и default вычисляются относительно текущей строки.

default должно иметь тот же тип, что и expression, однако это проверяется только базой данных, а не в Python.

MariaDB и default

MariaDB не поддерживает параметр default.

NthValue

class NthValue(expression, nth=1, **extra)

Вычисляет строку, относительную к смещению nth (должно быть положительным значением) внутри окна. Возвращает None , если такой строки нет.

Некоторые базы данных могут по-разному обрабатывать несуществующее n-е значение. Например, Oracle возвращает пустую строку вместо None для выражений с символами. Django в этих случаях не выполняет никаких преобразований.

Ntile

class Ntile(num_buckets=1, **extra)

Вычисляет раздел для каждой из строк в фрагменте, распределяя числа как можно равномернее между 1 и num_buckets. Если строки не делятся равномерно на количество блоков, один или несколько блоков будут представлены чаще.

PercentRank

class PercentRank(*expressions, **extra)

Вычисляет процентный ранг строк в фрагменте. Это вычисление эквивалентно оценке:

(rank - 1) / (total rows - 1)

Следующая таблица поясняет вычисление процентного ранга строки:

Номер строки Значение Ранг Вычисление Процентный ранг
1 15 1 (1-1)/(7-1) 0.0000
2 20 2 (2-1)/(7-1) 0.1666
3 20 2 (2-1)/(7-1) 0.1666
4 20 2 (2-1)/(7-1) 0.1666
5 30 5 (5-1)/(7-1) 0.6666
6 30 5 (5-1)/(7-1) 0.6666
7 40 7 (7-1)/(7-1) 1.0000

Rank

class Rank(*expressions, **extra)

Аналогично RowNumber, эта функция ранжирует строки в окне. Вычисленный ранг содержит пробелы. Используйте DenseRank для вычисления ранга без пробелов.

RowNumber

class RowNumber(*expressions, **extra)

Вычисляет номер строки в соответствии с упорядочением либо фрагмента запроса, либо всего запроса в целом, если нет разбиения фрагмента окна.

© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/3.1/ref/models/database-functions/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API