Функции базы данных
Описанные ниже классы предоставляют пользователям возможность использовать функции, поддерживаемые базовой базой данных, в 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)[исходный код]
Принимает список из как минимум двух имен полей или выражений и возвращает первое ненулевое значение (обратите внимание: пустая строка не считается нулевым значением). Все аргументы должны иметь схожий тип, поэтому смешение текста и чисел приведет к ошибке базы данных.
Примеры использования:
>>> # 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()))
Collate
-
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>]>
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. - SQLite, Oracle и MySQL: если любое выражение равно
null,Greatestвозвращаетnull.
Поведение PostgreSQL можно имитировать с помощью Coalesce, если вы знаете разумное минимальное значение, которое можно указать по умолчанию.
Least
-
class Least(*expressions, **extra)[исходный код]
Принимает список из как минимум двух имен полей или выражений и возвращает наименьшее значение. Все аргументы должны иметь схожий тип, поэтому смешение текста и чисел приведет к ошибке базы данных.
Предупреждение
Поведение Least, если одно или несколько выражений могут быть null, различается в разных базах данных:
- PostgreSQL:
Leastвозвращает наименьшее ненулевое выражение или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, обычно предоставляемый модулем zoneinfo.
Для даты и времени 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)[исходный код] -
Возвращает день недели 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.
Поскольку у DateFields нет компонента времени, с 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
Помимо перечисленных ниже, для DateTimeFields также можно использовать все перечисленные выше извлечения для DateField.
-
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 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}
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.
Oracle
В Oracle используется SQL LOCALTIMESTAMP, чтобы избежать проблем при приведении CURRENT_TIMESTAMP к DateTimeField.
Trunc
-
class Trunc(expression, kind, output_field=None, tzinfo=None, **extra)[исходный код]
Усекает дату до значимого компонента.
Если важно знать, произошло ли что-либо в определённом году, часу или дне, но не в конкретную секунду, Trunc (и его подклассы) может пригодиться для фильтрации или агрегации данных. Например, с помощью Trunc можно вычислить количество продаж за день.
Trunc принимает один expression, представляющий DateField, TimeField или DateTimeField, kind, представляющий часть даты или времени, и output_field, которое может быть DateTimeField(), TimeField() или DateField(). В зависимости от output_field функция возвращает дату и время, дату или время; поля вплоть до kind устанавливаются в минимальные значения. Если output_field не задано, по умолчанию используется output_field из expression. Для усечения значения в определённом часовом поясе можно передать подкласс tzinfo, обычно предоставляемый модулем zoneinfo.
Для даты и времени 2015-06-15 14:30:50.000321+00:00 встроенные kind возвращают:
- “year”: 2015-01-01 00:00:00+00:00
- “quarter”: 2015-04-01 00:00:00+00:00
- “month”: 2015-06-01 00:00:00+00:00
- “week”: 2015-06-15 00:00:00+00:00
- “day”: 2015-06-15 00:00:00+00:00
- “hour”: 2015-06-15 14:00:00+00:00
- “minute”: 2015-06-15 14:30:00+00:00
- “second”: 2015-06-15 14:30:50+00:00
Если в Django активен другой часовой пояс, например Australia/Melbourne, дата и время перед усечением значения преобразуются в новый часовой пояс. Смещение часового пояса для Мельбурна на указанную выше дату составляет +10:00. При активном часовом поясе будут возвращены следующие значения:
- “year”: 2015-01-01 00:00:00+11:00
- “quarter”: 2015-04-01 00:00:00+10:00
- “month”: 2015-06-01 00:00:00+10:00
- “week”: 2015-06-16 00:00:00+10:00
- “day”: 2015-06-16 00:00:00+10:00
- “hour”: 2015-06-16 00:00:00+10:00
- “minute”: 2015-06-16 00:30:00+10:00
- “second”: 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, **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). Они усекают все части даты вплоть до 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 приводит expression к типу даты, а не использует встроенную функцию усечения SQL. Он также зарегистрирован как преобразование для DateTimeField под именем __date.
-
class TruncTime(expression, tzinfo=None, **extra)[исходный код] -
- lookup_name = 'time'
- output_field = TimeField()
TruncTime приводит expression к типу времени, а не использует встроенную функцию усечения 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). Они усекают все части даты вплоть до kind и позволяют группировать или фильтровать даты и время с меньшей точностью. expression должен иметь 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
- classTruncHour(expression, output_field=None, tzinfo=None, **extra)[исходный код]
-
- kind = 'hour'
- classTruncMinute(expression, output_field=None, tzinfo=None, **extra)[исходный код]
-
- kind = 'minute'
- classTruncSecond(expression, output_field=None, tzinfo=None, **extra)[исходный код]
-
- kind = 'second'
Логически они эквивалентны Trunc('time_field', kind). Они усекают все части времени вплоть до 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
-
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()
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)[исходный код]
Принимает два числовых поля или выражения и возвращает остаток от деления первого на второе (операция взятия по модулю).
Пример использования:
>>> 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)
Random
-
class Random(**extra)[исходный код]
Возвращает случайное значение в диапазоне 0.0 ≤ x < 1.0.
Round
-
class Round(expression, precision=0, **extra)[исходный код]
Округляет числовое поле или выражение до precision (должно быть целым числом) знаков после запятой. По умолчанию округляет до ближайшего целого числа. Округление половинных значений вверх или вниз зависит от базы данных.
Пример использования:
>>> 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)
Sign
-
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)
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)[исходный код]
Принимает числовое поле или выражение и возвращает текстовое представление выражения в виде одного символа. Работает так же, как функция chr() в Python.
Как и 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(). При объединении Value, как в примере ниже, также необходимо указать output_field.
Эта функция никогда не возвращает null. В системах, где аргумент со значением null приводит к тому, что всё выражение становится null, Django сначала преобразует каждую часть со значением null в пустую строку.
Пример использования:
>>> # 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)[исходный код]
Принимает одно текстовое поле или выражение и возвращает хеш 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 первого символа выражения. Работает подобно функции ord() в Python, но исключение не возникает, если выражение содержит больше одного символа.
Её также можно зарегистрировать как преобразование, как описано в разделе 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)[исходный код]
Принимает одно текстовое поле или выражение и возвращает соответствующий хеш строки.
Их также можно зарегистрировать как преобразования, как описано в разделе 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/6.0/ref/models/database-functions/