• 3.1
  • 3.2
  • 5.0
  • Версия документации: 6.1

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

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

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

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 ниже.

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

В ролях

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

Объединиться

class Coalesce(*expressions, **extra)

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

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

>>> # Get a screen name from least to most public
>>> from django.db.models import Sum
>>> 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
>>> # The aggregate default argument uses Coalesce() under the hood.
>>> aggregated = Author.objects.aggregate(
...     combined_age=Sum("age"),
...     combined_age_default=Sum("age", default=0),
...     combined_age_coalesce=Coalesce(Sum("age"), 0),
... )
>>> print(aggregated["combined_age"])
None
>>> print(aggregated["combined_age_default"])
0
>>> print(aggregated["combined_age_coalesce"])
0

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

Значение 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()))

Сопоставить

class Collate(expression, collation)

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

Например, для фильтрации без учета регистра в SQLite:

>>> Author.objects.filter(name=Collate(Value("john"), "nocase"))
<QuerySet [<Author: John>, <Author: john>]>

Его также можно использовать при заказе, например с PostgreSQL:

>>> Author.objects.order_by(Collate("name", "et-x-icu"))
<QuerySet [<Author: Ursula>, <Author: Veronika>, <Author: Ülle>]>

Величайший

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.

  • SQLite, Oracle и MySQL: если какое-либо выражение имеет значение null, Greatest вернет null.

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

Наименее

class Least(*expressions, **extra)

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

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

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

  • PostgreSQL: Least вернет наименьшее ненулевое выражение или null, если все выражения равны null.

  • SQLite, Oracle и MySQL: если какое-либо выражение имеет значение null, функция Least вернет значение null.

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

NullIf

class NullIf(expression1, expression2)

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

Предостережения относительно Oracle

В соответствии с соглашением Oracle<oracle-null-empty-strings>` эта функция возвращает пустую строку вместо None, когда выражения имеют тип CharField.

Передача Value(None) в выражение1 запрещена в 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)

Экстракт

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

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

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

Учитывая дату и время 2015-06-15 23:30:01.000321+00:00, встроенный ищу_имяs возвращает:

  • «год»: 2015

  • «iso_year»: 2015 г.

  • «четверть»: 2

  • «месяц»: 6

  • «день»: 15

  • «неделя»: 25

  • «день_недели»: 2

  • «iso_week_day»: 1

  • «час»: 23

  • «минута»: 30

  • «второй»: 1

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

  • «день»: 16

  • «день_недели»: 3

  • «iso_week_day»: 2

  • «час»: 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

недельные значения

Неделя lookup_type рассчитывается на основе ``ISO-8601 <https://en.wikipedia.org/wiki/ISO-8601>`_, т. е. неделя начинается в понедельник. Первая неделя года — это та, которая содержит первый четверг года, т. е. на первую неделю приходится большинство (четыре или более) дней в году. Возвращаемое значение находится в диапазоне от 1 до 52 или 53.

Каждое «имя поиска» выше имеет соответствующий подкласс «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)

Возвращает день недели 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', искомое_имя). Каждый класс также является преобразованием, зарегистрированным в DateField и DateTimeField как __(lookup_name), например: __год.

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

>>> from datetime import UTC, datetime
>>> from django.db.models.functions import (
...     ExtractDay,
...     ExtractMonth,
...     ExtractQuarter,
...     ExtractWeek,
...     ExtractIsoWeekDay,
...     ExtractWeekDay,
...     ExtractIsoYear,
...     ExtractYear,
... )
>>> start_2015 = datetime(2015, 6, 15, 23, 30, 1, tzinfo=UTC)
>>> end_2015 = datetime(2015, 6, 16, 13, 11, 27, tzinfo=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, перечисленные выше, также могут использоваться в DateTimeFields.

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', искомое_имя). Каждый класс также является Transform, зарегистрированным в DateTimeField как __(lookup_name), например. __минута.

Примеры DateTimeField:

>>> from datetime import UTC, datetime
>>> 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=UTC)
>>> end_2015 = datetime(2015, 6, 16, 13, 11, 27, tzinfo=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), что изменяет возвращаемые значения дня, дня недели и часа:

>>> from django.utils import timezone
>>> import zoneinfo
>>> melb = zoneinfo.ZoneInfo("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 zoneinfo
>>> melb = zoneinfo.ZoneInfo("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}

Сейчас

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.

Оракул

В Oracle SQL LOCALTIMESTAMP используется во избежание проблем с преобразованием CURRENT_TIMESTAMP в DateTimeField.

Трунк

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

Усекает дату до значимого компонента.

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

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

Учитывая дату и время 2015-06-15 14:30:50.000321+00:00, встроенный kinds возвращает:

  • «год»: 01.01.2015 00:00:00+00:00

  • «квартал»: 01.04.2015 00:00:00+00:00

  • «месяц»: 01.06.2015 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

  • «второй»: 15.06.2015 14:30:50+00:00

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

  • «год»: 01.01.2015 00:00:00+11:00

  • «квартал»: 01.04.2015 00:00:00+10:00

  • «месяц»: 01.06.2015 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

  • «второй»: 16.06.2015 00:30:50+10:00

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

Каждому виду, указанному выше, соответствует соответствующий подкласс 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, **extra)
kind = 'year'
class TruncMonth(expression, output_field=None, tzinfo=None, **extra)
kind = 'month'
class TruncWeek(expression, output_field=None, tzinfo=None, **extra)

Усекается до полуночи понедельника недели.

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

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

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

>>> from datetime import UTC, datetime
>>> from django.db.models import Count
>>> from django.db.models.functions import TruncMonth, TruncYear
>>> start1 = datetime(2014, 6, 15, 14, 30, 50, 321, tzinfo=UTC)
>>> start2 = datetime(2015, 6, 15, 14, 40, 2, 123, tzinfo=UTC)
>>> start3 = datetime(2015, 12, 31, 17, 5, 27, 999, tzinfo=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 zoneinfo
>>> melb = zoneinfo.ZoneInfo("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, tzinfo=None, **extra)
lookup_name = 'date'
output_field = DateField()

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

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

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

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

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

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

>>> from datetime import UTC, date, datetime
>>> from django.db.models import Count
>>> from django.db.models.functions import (
...     TruncDate,
...     TruncDay,
...     TruncHour,
...     TruncMinute,
...     TruncSecond,
... )
>>> import zoneinfo
>>> start1 = datetime(2014, 6, 15, 14, 30, 50, 321, tzinfo=UTC)
>>> Experiment.objects.create(start_datetime=start1, start_date=start1.date())
>>> melb = zoneinfo.ZoneInfo("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=zoneinfo.ZoneInfo('Australia/Melbourne')),
 'hour': datetime.datetime(2014, 6, 16, 0, 0, tzinfo=zoneinfo.ZoneInfo('Australia/Melbourne')),
 '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, **extra)
kind = 'hour'
class TruncMinute(expression, output_field=None, tzinfo=None, **extra)
kind = 'minute'
class TruncSecond(expression, output_field=None, tzinfo=None, **extra)
kind = 'second'

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

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

>>> from datetime import UTC, datetime
>>> from django.db.models import Count, TimeField
>>> from django.db.models.functions import TruncHour
>>> start1 = datetime(2014, 6, 15, 14, 30, 50, 321, tzinfo=UTC)
>>> start2 = datetime(2014, 6, 15, 14, 40, 2, 123, tzinfo=UTC)
>>> start3 = datetime(2015, 12, 31, 17, 5, 27, 999, tzinfo=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 zoneinfo
>>> melb = zoneinfo.ZoneInfo("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

JSON-функции

JSONArray

New in Django 5.2.
class JSONArray(*expressions)

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

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

>>> from django.db.models import F
>>> from django.db.models.functions import JSONArray, Lower
>>> Author.objects.create(name="Margaret Smith", alias="msmith", age=25)
>>> author = Author.objects.annotate(
...     json_array=JSONArray(
...         Lower("name"),
...         "alias",
...         F("age") * 2,
...     )
... ).get()
>>> author.json_array
['margaret smith', 'msmith', 50]

JSONObject

class JSONObject(**fields)

Берет список пар ключ-значение и возвращает объект JSON, содержащий эти пары.

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

>>> from django.db.models import F
>>> from django.db.models.functions import JSONObject, Lower
>>> Author.objects.create(name="Margaret Smith", alias="msmith", age=25)
>>> author = Author.objects.annotate(
...     json_object=JSONObject(
...         name=Lower("name"),
...         alias="alias",
...         age=F("age") * 2,
...     )
... ).get()
>>> author.json_object
{'name': 'margaret smith', 'alias': 'msmith', 'age': 50}

Математические функции

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

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

Абс

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)

АСин

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)

АТан

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)

Возвращает арктангенс выражения1/выражения2.

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

>>> 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

Клетка

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)

Кос

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)

Детская кроватка

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)

Градусы

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)

Этаж

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)

Лн

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)

Журнал

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

Мод

class Mod(expression1, expression2, **extra)

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

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

>>> 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

Пи

class Pi(**extra)

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

Власть

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

Радиан

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)

Случайный

class Random(**extra)

Возвращает случайное значение в диапазоне 0,0 x < 1,0.

Круглый

class Round(expression, precision=0, **extra)

Округляет числовое поле или выражение до десятичных знаков точности (должно быть целым числом). По умолчанию оно округляется до ближайшего целого числа. Округление половинных значений в большую или меньшую сторону зависит от базы данных.

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

>>> from django.db.models.functions import Round
>>> Vector.objects.create(x=5.4, y=-2.37)
>>> vector = Vector.objects.annotate(x_r=Round("x"), y_r=Round("y", precision=1)).get()
>>> vector.x_r, vector.y_r
(5.0, -2.4)

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

>>> 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)

Подписать

class Sign(expression, **extra)

Возвращает знак (-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)

Грех

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)

Квадрат

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)

Тан

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)

Текстовые функции

Кр

class Chr(expression, **extra)

Принимает числовое поле или выражение и возвращает текстовое представление выражения в виде одного символа. Она работает так же, как функция Python 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

Конкат

class Concat(*expressions, **extra)

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

Эта функция никогда не будет иметь нулевой результат. На бэкэндах, где нулевой аргумент приводит к тому, что все выражение становится нулевым, 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)

Слева

class Left(expression, length, **extra)

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

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

>>> 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

Длина

class Length(expression, **extra)

Принимает одно текстовое поле или выражение и возвращает количество символов, содержащихся в значении. Если выражение имеет значение 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)

Нижний

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)

Принимает одно текстовое поле или выражение и возвращает хэш 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

Орд

class Ord(expression, **extra)

Принимает одно текстовое поле или выражение и возвращает значение кодовой точки Юникода для первого символа этого выражения. Она работает аналогично функции Python 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

Повторить

class Repeat(expression, number, **extra)

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

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

>>> 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

Заменить

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

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

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

>>> 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'}]>

Реверс

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

Правильно

class Right(expression, length, **extra)

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

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

>>> 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

Рпад

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)

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

Их также можно зарегистрировать как преобразования, как описано в 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 не поддерживает функцию SHA224.

СтрИндекс

class StrIndex(expression, substring, **extra)

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

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

>>> 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 параметр collation таблицы базы данных определяет, учитывается ли регистр при сравнении строк (таких как выражение и подстрока этой функции). По умолчанию сравнения не учитывают регистр.

Субстр

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

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

Обрезать

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

Верхний

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, но не имеет пробелов.

ПервоеЗначение

class FirstValue(expression, **extra)

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

Лаг

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

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

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

MariaDB и по умолчанию

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

LastValue

class LastValue(expression, **extra)

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

Свинец

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

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

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

MariaDB и по умолчанию

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

NthValue

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

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

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

Нтиле

class Ntile(num_buckets=1, **extra)

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

ПроцентРанк

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

Ранг

class Rank(*expressions, **extra)

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

Номер_строки

class RowNumber(*expressions, **extra)

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

Back to Top