Функции базы данных¶
Классы, описанные ниже, предоставляют пользователям возможность использовать функции, предоставляемые базой данных, в качестве аннотаций, агрегаций или фильтров в Django. Функции также являются expressions, поэтому их можно использовать и комбинировать с другими выражениями, такими как aggregate functions.
В примерах каждой функции мы будем использовать следующую модель:
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)[исходный код]¶
Принимает выражение и имя 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
, если вы знаете разумное минимальное значение по умолчанию.
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}
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 convention эта функция возвращает пустую строку вместо 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
s возвращаются:
- «год»: 2015
- «iso_year»: 2015
- «квартал»: 2
- «месяц»: 6
- «день»: 15
- «неделя»: 25
- «week_day»: 2
- «iso_week_day»: 1
- «час»: 23
- «минута»: 30
- «second»: 1
Если в Django активен другой часовой пояс, например Australia/Melbourne
, то перед извлечением значения дататайм преобразуется в часовой пояс. Смещение часового пояса для Мельбурна в приведенном выше примере даты составляет +10:00. Значения, возвращаемые при активном часовом поясе, будут такими же, как и выше, за исключением:
- «день»: 16
- «week_day»: 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
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
.
Поскольку DateField
не имеет компонента времени, с DateField
можно использовать только подклассы Extract
, работающие с компонентами даты:
>>> from datetime import datetime, timezone
>>> from django.db.models.functions import (
... ExtractDay,
... ExtractMonth,
... ExtractQuarter,
... ExtractWeek,
... ExtractIsoWeekDay,
... ExtractWeekDay,
... ExtractIsoYear,
... ExtractYear,
... )
>>> start_2015 = datetime(2015, 6, 15, 23, 30, 1, tzinfo=timezone.utc)
>>> end_2015 = datetime(2015, 6, 16, 13, 11, 27, tzinfo=timezone.utc)
>>> Experiment.objects.create(
... start_datetime=start_2015,
... start_date=start_2015.date(),
... end_datetime=end_2015,
... end_date=end_2015.date(),
... )
>>> Experiment.objects.annotate(
... year=ExtractYear("start_date"),
... isoyear=ExtractIsoYear("start_date"),
... quarter=ExtractQuarter("start_date"),
... month=ExtractMonth("start_date"),
... week=ExtractWeek("start_date"),
... day=ExtractDay("start_date"),
... weekday=ExtractWeekDay("start_date"),
... isoweekday=ExtractIsoWeekDay("start_date"),
... ).values(
... "year",
... "isoyear",
... "quarter",
... "month",
... "week",
... "day",
... "weekday",
... "isoweekday",
... ).get(
... end_date__year=ExtractYear("start_date")
... )
{'year': 2015, 'isoyear': 2015, 'quarter': 2, 'month': 6, 'week': 25,
'day': 15, 'weekday': 2, 'isoweekday': 1}
DateTimeField
экстракты¶
Кроме того, все перечисленные выше экстракты для DateField
могут быть использованы и для DateTimeField
s .
-
class
ExtractHour
(expression, tzinfo=None, **extra)[исходный код]¶ -
lookup_name = 'hour'
-
-
class
ExtractMinute
(expression, tzinfo=None, **extra)[исходный код]¶ -
lookup_name = 'minute'
-
-
class
ExtractSecond
(expression, tzinfo=None, **extra)[исходный код]¶ -
lookup_name = 'second'
-
Они логически эквивалентны Extract('datetime_field', lookup_name)
. Каждый класс также является Transform
, зарегистрированным на DateTimeField
как __(lookup_name)
, например, __minute
.
DateTimeField
примеры:
>>> from datetime import datetime, timezone
>>> from django.db.models.functions import (
... ExtractDay,
... ExtractHour,
... ExtractMinute,
... ExtractMonth,
... ExtractQuarter,
... ExtractSecond,
... ExtractWeek,
... ExtractIsoWeekDay,
... ExtractWeekDay,
... ExtractIsoYear,
... ExtractYear,
... )
>>> start_2015 = datetime(2015, 6, 15, 23, 30, 1, tzinfo=timezone.utc)
>>> end_2015 = datetime(2015, 6, 16, 13, 11, 27, tzinfo=timezone.utc)
>>> Experiment.objects.create(
... start_datetime=start_2015,
... start_date=start_2015.date(),
... end_datetime=end_2015,
... end_date=end_2015.date(),
... )
>>> Experiment.objects.annotate(
... year=ExtractYear("start_datetime"),
... isoyear=ExtractIsoYear("start_datetime"),
... quarter=ExtractQuarter("start_datetime"),
... month=ExtractMonth("start_datetime"),
... week=ExtractWeek("start_datetime"),
... day=ExtractDay("start_datetime"),
... weekday=ExtractWeekDay("start_datetime"),
... isoweekday=ExtractIsoWeekDay("start_datetime"),
... hour=ExtractHour("start_datetime"),
... minute=ExtractMinute("start_datetime"),
... second=ExtractSecond("start_datetime"),
... ).values(
... "year",
... "isoyear",
... "month",
... "week",
... "day",
... "weekday",
... "isoweekday",
... "hour",
... "minute",
... "second",
... ).get(
... end_datetime__year=ExtractYear("start_datetime")
... )
{'year': 2015, 'isoyear': 2015, 'quarter': 2, 'month': 6, 'week': 25,
'day': 15, 'weekday': 2, 'isoweekday': 1, 'hour': 23, 'minute': 30,
'second': 1}
Если USE_TZ
имеет значение True
, то даты хранятся в базе данных в формате UTC. Если в Django используется другой часовой пояс, то перед извлечением значения дататайм преобразуется в этот часовой пояс. В приведенном ниже примере преобразование выполняется в часовой пояс Мельбурна (UTC +10:00), что приводит к изменению возвращаемых значений дня, дня недели и часа:
>>> 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
.
Добавлена поддержка микросекундной точности для MySQL и миллисекундной точности для SQLite.
В старых версиях SQL CURRENT_TIMESTAMP
использовался в Oracle вместо LOCALTIMESTAMP
.
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
s возвращаются:
- «год»: 2015-01-01 00:00:00+00:00
- «квартал»: 2015-04-01 00:00:00+00:00
- «месяц»: 2015-06-01 00:00:00+00:00
- «неделя»: 2015-06-15 00:00:00+00:00
- «день»: 2015-06-15 00:00:00+00:00
- «час»: 2015-06-15 14:00:00+00:00
- «минута»: 2015-06-15 14:30:00+00:00
- «второй»: 2015-06-15 14:30:50+00:00
Если в Django активен другой часовой пояс, например Australia/Melbourne
, то дататайм конвертируется в новый часовой пояс перед усечением значения. Смещение часового пояса для Мельбурна в приведенном выше примере даты составляет +10:00. Значения, возвращаемые при активном часовом поясе, будут следующими:
- «год»: 2015-01-01 00:00:00+11:00
- «квартал»: 2015-04-01 00:00:00+10:00
- «месяц»: 2015-06-01 00:00:00+10:00
- «неделя»: 2015-06-16 00:00:00+10:00
- «день»: 2015-06-16 00:00:00+10:00
- «час»: 2015-06-16 00:00:00+10:00
- «минута»: 2015-06-16 00:30:00+10:00
- «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
.
Поскольку DateField
не имеет компонента времени, с DateField
можно использовать только подклассы Trunc
, работающие с компонентами даты:
>>> from datetime import datetime, timezone
>>> from django.db.models import Count
>>> from django.db.models.functions import TruncMonth, TruncYear
>>> start1 = datetime(2014, 6, 15, 14, 30, 50, 321, tzinfo=timezone.utc)
>>> start2 = datetime(2015, 6, 15, 14, 40, 2, 123, tzinfo=timezone.utc)
>>> start3 = datetime(2015, 12, 31, 17, 5, 27, 999, tzinfo=timezone.utc)
>>> Experiment.objects.create(start_datetime=start1, start_date=start1.date())
>>> Experiment.objects.create(start_datetime=start2, start_date=start2.date())
>>> Experiment.objects.create(start_datetime=start3, start_date=start3.date())
>>> experiments_per_year = (
... Experiment.objects.annotate(year=TruncYear("start_date"))
... .values("year")
... .annotate(experiments=Count("id"))
... )
>>> for exp in experiments_per_year:
... print(exp["year"], exp["experiments"])
...
2014-01-01 1
2015-01-01 2
>>> import 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 truncate. Она также зарегистрирована как преобразование DateTimeField
в __date
.
-
class
TruncTime
(expression, tzinfo=None, **extra)[исходный код]¶ -
lookup_name = 'time'
-
output_field = TimeField()
-
TruncTime
приводит expression
к времени, а не использует встроенную функцию SQL truncate. Она также зарегистрирована как преобразование 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 date, datetime, timezone
>>> 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=timezone.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=timezone.utc),
'second': datetime.datetime(2014, 6, 15, 14, 30, 50, tzinfo=timezone.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)
. Они усекают все части времени до kind
, что позволяет группировать или фильтровать время с меньшей точностью. expression
может иметь output_field
либо TimeField
, либо DateTimeField
.
Поскольку TimeField
не имеет компонента даты, с TimeField
можно использовать только подклассы Trunc
, работающие с временными частями:
>>> from datetime import datetime, timezone
>>> from django.db.models import Count, TimeField
>>> from django.db.models.functions import TruncHour
>>> start1 = datetime(2014, 6, 15, 14, 30, 50, 321, tzinfo=timezone.utc)
>>> start2 = datetime(2014, 6, 15, 14, 40, 2, 123, tzinfo=timezone.utc)
>>> start3 = datetime(2015, 12, 31, 17, 5, 27, 999, tzinfo=timezone.utc)
>>> Experiment.objects.create(start_datetime=start1, start_time=start1.time())
>>> Experiment.objects.create(start_datetime=start2, start_time=start2.time())
>>> Experiment.objects.create(start_datetime=start3, start_time=start3.time())
>>> experiments_per_hour = (
... Experiment.objects.annotate(
... hour=TruncHour("start_datetime", output_field=TimeField()),
... )
... .values("hour")
... .annotate(experiments=Count("id"))
... )
>>> for exp in experiments_per_hour:
... print(exp["hour"], exp["experiments"])
...
14:00:00 2
17:00:00 1
>>> import 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
Математические функции¶
В примерах математических функций мы будем использовать следующую модель:
class Vector(models.Model):
x = models.FloatField()
y = models.FloatField()
Abs
¶
-
class
Abs
(expression, **extra)[исходный код]¶
Возвращает абсолютное значение числового поля или выражения.
Пример использования:
>>> from django.db.models.functions import Abs
>>> Vector.objects.create(x=-0.5, y=1.1)
>>> vector = Vector.objects.annotate(x_abs=Abs("x"), y_abs=Abs("y")).get()
>>> vector.x_abs, vector.y_abs
(0.5, 1.1)
Он также может быть зарегистрирован как преобразование. Например:
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Abs
>>> FloatField.register_lookup(Abs)
>>> # Get vectors inside the unit cube
>>> vectors = Vector.objects.filter(x__abs__lt=1, y__abs__lt=1)
ACos
¶
-
class
ACos
(expression, **extra)[исходный код]¶
Возвращает арккосинус числового поля или выражения. Значение выражения должно находиться в диапазоне от -1 до 1.
Пример использования:
>>> from django.db.models.functions import ACos
>>> Vector.objects.create(x=0.5, y=-0.9)
>>> vector = Vector.objects.annotate(x_acos=ACos("x"), y_acos=ACos("y")).get()
>>> vector.x_acos, vector.y_acos
(1.0471975511965979, 2.6905658417935308)
Он также может быть зарегистрирован как преобразование. Например:
>>> from django.db.models import FloatField
>>> from django.db.models.functions import ACos
>>> FloatField.register_lookup(ACos)
>>> # Get vectors whose arccosine is less than 1
>>> vectors = Vector.objects.filter(x__acos__lt=1, y__acos__lt=1)
ASin
¶
-
class
ASin
(expression, **extra)[исходный код]¶
Возвращает арксинус числового поля или выражения. Значение выражения должно находиться в диапазоне от -1 до 1.
Пример использования:
>>> from django.db.models.functions import ASin
>>> Vector.objects.create(x=0, y=1)
>>> vector = Vector.objects.annotate(x_asin=ASin("x"), y_asin=ASin("y")).get()
>>> vector.x_asin, vector.y_asin
(0.0, 1.5707963267948966)
Он также может быть зарегистрирован как преобразование. Например:
>>> from django.db.models import FloatField
>>> from django.db.models.functions import ASin
>>> FloatField.register_lookup(ASin)
>>> # Get vectors whose arcsine is less than 1
>>> vectors = Vector.objects.filter(x__asin__lt=1, y__asin__lt=1)
ATan
¶
-
class
ATan
(expression, **extra)[исходный код]¶
Возвращает арктангенс числового поля или выражения.
Пример использования:
>>> from django.db.models.functions import ATan
>>> Vector.objects.create(x=3.12, y=6.987)
>>> vector = Vector.objects.annotate(x_atan=ATan("x"), y_atan=ATan("y")).get()
>>> vector.x_atan, vector.y_atan
(1.2606282660069106, 1.428638798133829)
Он также может быть зарегистрирован как преобразование. Например:
>>> from django.db.models import FloatField
>>> from django.db.models.functions import ATan
>>> FloatField.register_lookup(ATan)
>>> # Get vectors whose arctangent is less than 2
>>> vectors = Vector.objects.filter(x__atan__lt=2, y__atan__lt=2)
ATan2
¶
-
class
ATan2
(expression1, expression2, **extra)[исходный код]¶
Возвращает арктангенс от expression1 / expression2
.
Пример использования:
>>> from django.db.models.functions import ATan2
>>> Vector.objects.create(x=2.5, y=1.9)
>>> vector = Vector.objects.annotate(atan2=ATan2("x", "y")).get()
>>> vector.atan2
0.9209258773829491
Ceil
¶
-
class
Ceil
(expression, **extra)[исходный код]¶
Возвращает наименьшее целое число, большее или равное числовому полю или выражению.
Пример использования:
>>> from django.db.models.functions import Ceil
>>> Vector.objects.create(x=3.12, y=7.0)
>>> vector = Vector.objects.annotate(x_ceil=Ceil("x"), y_ceil=Ceil("y")).get()
>>> vector.x_ceil, vector.y_ceil
(4.0, 7.0)
Он также может быть зарегистрирован как преобразование. Например:
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Ceil
>>> FloatField.register_lookup(Ceil)
>>> # Get vectors whose ceil is less than 10
>>> vectors = Vector.objects.filter(x__ceil__lt=10, y__ceil__lt=10)
Cos
¶
-
class
Cos
(expression, **extra)[исходный код]¶
Возвращает косинус числового поля или выражения.
Пример использования:
>>> from django.db.models.functions import Cos
>>> Vector.objects.create(x=-8.0, y=3.1415926)
>>> vector = Vector.objects.annotate(x_cos=Cos("x"), y_cos=Cos("y")).get()
>>> vector.x_cos, vector.y_cos
(-0.14550003380861354, -0.9999999999999986)
Он также может быть зарегистрирован как преобразование. Например:
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Cos
>>> FloatField.register_lookup(Cos)
>>> # Get vectors whose cosine is less than 0.5
>>> vectors = Vector.objects.filter(x__cos__lt=0.5, y__cos__lt=0.5)
Cot
¶
-
class
Cot
(expression, **extra)[исходный код]¶
Возвращает котангенс числового поля или выражения.
Пример использования:
>>> from django.db.models.functions import Cot
>>> Vector.objects.create(x=12.0, y=1.0)
>>> vector = Vector.objects.annotate(x_cot=Cot("x"), y_cot=Cot("y")).get()
>>> vector.x_cot, vector.y_cot
(-1.5726734063976826, 0.642092615934331)
Он также может быть зарегистрирован как преобразование. Например:
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Cot
>>> FloatField.register_lookup(Cot)
>>> # Get vectors whose cotangent is less than 1
>>> vectors = Vector.objects.filter(x__cot__lt=1, y__cot__lt=1)
Degrees
¶
-
class
Degrees
(expression, **extra)[исходный код]¶
Преобразует числовое поле или выражение из радианов в градусы.
Пример использования:
>>> from django.db.models.functions import Degrees
>>> Vector.objects.create(x=-1.57, y=3.14)
>>> vector = Vector.objects.annotate(x_d=Degrees("x"), y_d=Degrees("y")).get()
>>> vector.x_d, vector.y_d
(-89.95437383553924, 179.9087476710785)
Он также может быть зарегистрирован как преобразование. Например:
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Degrees
>>> FloatField.register_lookup(Degrees)
>>> # Get vectors whose degrees are less than 360
>>> vectors = Vector.objects.filter(x__degrees__lt=360, y__degrees__lt=360)
Exp
¶
-
class
Exp
(expression, **extra)[исходный код]¶
Возвращает значение e
(основание натурального логарифма), возведенное в степень числового поля или выражения.
Пример использования:
>>> from django.db.models.functions import Exp
>>> Vector.objects.create(x=5.4, y=-2.0)
>>> vector = Vector.objects.annotate(x_exp=Exp("x"), y_exp=Exp("y")).get()
>>> vector.x_exp, vector.y_exp
(221.40641620418717, 0.1353352832366127)
Он также может быть зарегистрирован как преобразование. Например:
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Exp
>>> FloatField.register_lookup(Exp)
>>> # Get vectors whose exp() is greater than 10
>>> vectors = Vector.objects.filter(x__exp__gt=10, y__exp__gt=10)
Floor
¶
-
class
Floor
(expression, **extra)[исходный код]¶
Возвращает наибольшее целочисленное значение, не превышающее числовое поле или выражение.
Пример использования:
>>> from django.db.models.functions import Floor
>>> Vector.objects.create(x=5.4, y=-2.3)
>>> vector = Vector.objects.annotate(x_floor=Floor("x"), y_floor=Floor("y")).get()
>>> vector.x_floor, vector.y_floor
(5.0, -3.0)
Он также может быть зарегистрирован как преобразование. Например:
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Floor
>>> FloatField.register_lookup(Floor)
>>> # Get vectors whose floor() is greater than 10
>>> vectors = Vector.objects.filter(x__floor__gt=10, y__floor__gt=10)
Ln
¶
-
class
Ln
(expression, **extra)[исходный код]¶
Возвращает натуральный логарифм числового поля или выражения.
Пример использования:
>>> from django.db.models.functions import Ln
>>> Vector.objects.create(x=5.4, y=233.0)
>>> vector = Vector.objects.annotate(x_ln=Ln("x"), y_ln=Ln("y")).get()
>>> vector.x_ln, vector.y_ln
(1.6863989535702288, 5.4510384535657)
Он также может быть зарегистрирован как преобразование. Например:
>>> from django.db.models import FloatField
>>> from django.db.models.functions import Ln
>>> FloatField.register_lookup(Ln)
>>> # Get vectors whose value greater than e
>>> vectors = Vector.objects.filter(x__ln__gt=1, y__ln__gt=1)
Log
¶
-
class
Log
(expression1, expression2, **extra)[исходный код]¶
Принимает два числовых поля или выражения и возвращает логарифм второго по основанию первого.
Пример использования:
>>> from django.db.models.functions import Log
>>> Vector.objects.create(x=2.0, y=4.0)
>>> vector = Vector.objects.annotate(log=Log("x", "y")).get()
>>> vector.log
2.0
Mod
¶
-
class
Mod
(expression1, expression2, **extra)[исходный код]¶
Принимает два числовых поля или выражения и возвращает остаток от деления первого на второе (операция modulo).
Пример использования:
>>> from django.db.models.functions import Mod
>>> Vector.objects.create(x=5.4, y=2.3)
>>> vector = Vector.objects.annotate(mod=Mod("x", "y")).get()
>>> vector.mod
0.8
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)[исходный код]¶
Принимает числовое поле или выражение и возвращает текстовое представление выражения в виде одного символа. Работает так же, как и функция 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
Concat
¶
-
class
Concat
(*expressions, **extra)[исходный код]¶
Принимает список из как минимум двух текстовых полей или выражений и возвращает конкатенированный текст. Каждый аргумент должен иметь тип text или char. Если вы хотите объединить 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)
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 для первого символа этого выражения. Работает аналогично функции 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
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 extension. Для его установки можно использовать операцию миграции 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 параметр collation таблицы базы данных определяет, являются ли сравнения строк (такие как 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 doesn’t support параметр default
.
LastValue
¶
-
class
LastValue
(expression, **extra)[исходный код]¶
Сравнимо с FirstValue
, вычисляет последнее значение в данном фрейме.
Lead
¶
-
class
Lead
(expression, offset=1, default=None, **extra)[исходный код]¶
Вычисляет ведущее значение в заданном frame. И offset
, и default
оцениваются относительно текущей строки.
default
должен иметь тот же тип, что и expression
, однако это проверяется только в базе данных, а не в Python.
MariaDB и default
MariaDB doesn’t support параметр default
.
NthValue
¶
-
class
NthValue
(expression, nth=1, **extra)[исходный код]¶
Вычисляет строку относительно смещения nth
(должно быть положительное значение) в пределах окна. Возвращает None
, если ряд не существует.
Некоторые базы данных могут по-разному обрабатывать несуществующее n-ое значение. Например, Oracle возвращает пустую строку, а не None
для выражений на основе символов. Django не делает никаких преобразований в этих случаях.
Ntile
¶
-
class
Ntile
(num_buckets=1, **extra)[исходный код]¶
Вычисляет раздел для каждой из строк в предложении frame, распределяя числа как можно более равномерно между 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)[исходный код]¶
Вычисляет номер строки в соответствии с упорядочиванием либо клаузулы frame, либо упорядочиванием всего запроса, если нет разбиения window frame.