Spec-Zone.ru › Django 1.11

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

Классы, описанные ниже, предоставляют способ для пользователей использовать функции, предоставляемые основной базой данных, как аннотации, агрегации или фильтры в 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) [source]
Новая функция в Django 1.10.

Принудительно задаёт тип результата expression на тип, указанный в output_field.

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

>>> from django.db.models import FloatField
>>> from django.db.models.functions import Cast
>>> Value.objects.create(integer=4)
>>> value = Value.objects.annotate(as_float=Cast('integer', FloatField())).get()
>>> print(value.as_float)
4.0

Coalesce

class Coalesce(*expressions, **extra) [source]

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

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

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

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

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

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

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

Concat

class Concat(*expressions, **extra) [source]

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

Эта функция никогда не вернёт 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)

Greatest

class Greatest(*expressions, **extra) [source]

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

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

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) [source]

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

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

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

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

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

Length

class Length(expression, **extra) [source]

Принимает одно текстовое поле или выражение и возвращает количество символов в значении. Если выражение 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, 'length')
>>> # Get authors whose name is longer than 7 characters
>>> authors = Author.objects.filter(name__length__gt=7)

Lower

class Lower(expression, **extra) [source]

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

Он также может быть зарегистрирован как преобразование, как описано в 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

Now

class Now [source]

Возвращает текущую дату и время сервера базы данных во время выполнения запроса, обычно используя 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.

Substr

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

Возвращает подстроку длины 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 Substr, Lower
>>> 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

Upper

class Upper(expression, **extra) [source]

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

Он также может быть зарегистрирован как преобразование, как описано в 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

Функции дат

Новая функция в Django 1.10.

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

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) [source]

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

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

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

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

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

  • “day”: 16
  • “week_day”: 3
  • “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) [source]
lookup_name = 'year'
class ExtractMonth(expression, tzinfo=None, **extra) [source]
lookup_name = 'month'
class ExtractDay(expression, tzinfo=None, **extra) [source]
lookup_name = 'day'
class ExtractWeekDay(expression, tzinfo=None, **extra) [source]
lookup_name = 'week_day'
class ExtractWeek(expression, tzinfo=None, **extra) [source]
Добавлена в Django 1.11.
lookup_name = 'week'

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

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

>>> from datetime import datetime
>>> from django.utils import timezone
>>> from django.db.models.functions import (
...     ExtractDay, ExtractMonth, ExtractWeek, ExtractWeekDay, 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'),
...     month=ExtractMonth('start_date'),
...     week=ExtractWeek('start_date'),
...     day=ExtractDay('start_date'),
...     weekday=ExtractWeekDay('start_date'),
... ).values('year', 'month', 'week', 'day', 'weekday').get(
...     end_date__year=ExtractYear('start_date'),
... )
{'year': 2015, 'month': 6, 'week': 25, 'day': 15, 'weekday': 2}

DateTimeField извлечения

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

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

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

DateTimeField примеры:

>>> from datetime import datetime
>>> from django.utils import timezone
>>> from django.db.models.functions import (
...     ExtractDay, ExtractHour, ExtractMinute, ExtractMonth, ExtractSecond,
...     ExtractWeek, ExtractWeekDay, 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'),
...     month=ExtractMonth('start_datetime'),
...     week=ExtractWeek('start_datetime'),
...     day=ExtractDay('start_datetime'),
...     weekday=ExtractWeekDay('start_datetime'),
...     hour=ExtractHour('start_datetime'),
...     minute=ExtractMinute('start_datetime'),
...     second=ExtractSecond('start_datetime'),
... ).values(
...     'year', 'month', 'week', 'day', 'weekday', 'hour', 'minute', 'second',
... ).get(end_datetime__year=ExtractYear('start_datetime'))
{'year': 2015, 'month': 6, 'week': 25, 'day': 15, 'weekday': 2, 'hour': 23,
 'minute': 30, 'second': 1}

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

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

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

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

Trunc

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

Округляет дату до значимой составляющей.

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

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

Учитывая datetime 2015-06-15 14:30:50.000321+00:00, встроенные kind возвращают:

  • “год”: 2015-01-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 14:00:00+00:00
  • “минута”: 2015-06-15 14:30:00+00:00
  • “секунда”: 2015-06-15 14:30:50+00:00

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

  • “год”: 2015-01-01 00:00:00+11: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:30:00+10:00
  • “секунда”: 2015-06-16 00:30:50+10:00

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

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

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

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

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

DateField округление

class TruncYear(expression, output_field=None, tzinfo=None, **extra) [source]
kind = 'year'
class TruncMonth(expression, output_field=None, tzinfo=None, **extra) [source]
kind = 'month'

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

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

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

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

TimeField округление

Добавлена в Django 1.11.
class TruncHour(expression, output_field=None, tzinfo=None, **extra) [source]
kind = 'hour'
class TruncMinute(expression, output_field=None, tzinfo=None, **extra) [source]
kind = 'minute'
class TruncSecond(expression, output_field=None, tzinfo=None, **extra) [source]
kind = 'second'

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

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

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

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

DateTimeField обрезка

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

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

class TruncTime(expression, **extra) [source]
Новое в Django 1.11:
lookup_name = 'time'
output_field = TimeField()

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

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

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

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

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

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

Spec-Zone.ru

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