database-functions.txt 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817
  1. ==================
  2. Database Functions
  3. ==================
  4. .. module:: django.db.models.functions
  5. :synopsis: Database Functions
  6. The classes documented below provide a way for users to use functions provided
  7. by the underlying database as annotations, aggregations, or filters in Django.
  8. Functions are also :doc:`expressions <expressions>`, so they can be used and
  9. combined with other expressions like :ref:`aggregate functions
  10. <aggregation-functions>`.
  11. We'll be using the following model in examples of each function::
  12. class Author(models.Model):
  13. name = models.CharField(max_length=50)
  14. age = models.PositiveIntegerField(null=True, blank=True)
  15. alias = models.CharField(max_length=50, null=True, blank=True)
  16. goes_by = models.CharField(max_length=50, null=True, blank=True)
  17. We don't usually recommend allowing ``null=True`` for ``CharField`` since this
  18. allows the field to have two "empty values", but it's important for the
  19. ``Coalesce`` example below.
  20. ``Cast``
  21. ========
  22. .. class:: Cast(expression, output_field)
  23. Forces the result type of ``expression`` to be the one from ``output_field``.
  24. Usage example::
  25. >>> from django.db.models import FloatField
  26. >>> from django.db.models.functions import Cast
  27. >>> Value.objects.create(integer=4)
  28. >>> value = Value.objects.annotate(as_float=Cast('integer', FloatField())).get()
  29. >>> print(value.as_float)
  30. 4.0
  31. ``Coalesce``
  32. ============
  33. .. class:: Coalesce(*expressions, **extra)
  34. Accepts a list of at least two field names or expressions and returns the
  35. first non-null value (note that an empty string is not considered a null
  36. value). Each argument must be of a similar type, so mixing text and numbers
  37. will result in a database error.
  38. Usage examples::
  39. >>> # Get a screen name from least to most public
  40. >>> from django.db.models import Sum, Value as V
  41. >>> from django.db.models.functions import Coalesce
  42. >>> Author.objects.create(name='Margaret Smith', goes_by='Maggie')
  43. >>> author = Author.objects.annotate(
  44. ... screen_name=Coalesce('alias', 'goes_by', 'name')).get()
  45. >>> print(author.screen_name)
  46. Maggie
  47. >>> # Prevent an aggregate Sum() from returning None
  48. >>> aggregated = Author.objects.aggregate(
  49. ... combined_age=Coalesce(Sum('age'), V(0)),
  50. ... combined_age_default=Sum('age'))
  51. >>> print(aggregated['combined_age'])
  52. 0
  53. >>> print(aggregated['combined_age_default'])
  54. None
  55. .. warning::
  56. A Python value passed to ``Coalesce`` on MySQL may be converted to an
  57. incorrect type unless explicitly cast to the correct database type:
  58. >>> from django.db.models import DateTimeField
  59. >>> from django.db.models.functions import Cast, Coalesce
  60. >>> from django.utils import timezone
  61. >>> now = timezone.now()
  62. >>> Coalesce('updated', Cast(now, DateTimeField()))
  63. ``Concat``
  64. ==========
  65. .. class:: Concat(*expressions, **extra)
  66. Accepts a list of at least two text fields or expressions and returns the
  67. concatenated text. Each argument must be of a text or char type. If you want
  68. to concatenate a ``TextField()`` with a ``CharField()``, then be sure to tell
  69. Django that the ``output_field`` should be a ``TextField()``. This is also
  70. required when concatenating a ``Value`` as in the example below.
  71. This function will never have a null result. On backends where a null argument
  72. results in the entire expression being null, Django will ensure that each null
  73. part is converted to an empty string first.
  74. Usage example::
  75. >>> # Get the display name as "name (goes_by)"
  76. >>> from django.db.models import CharField, Value as V
  77. >>> from django.db.models.functions import Concat
  78. >>> Author.objects.create(name='Margaret Smith', goes_by='Maggie')
  79. >>> author = Author.objects.annotate(
  80. ... screen_name=Concat('name', V(' ('), 'goes_by', V(')'),
  81. ... output_field=CharField())).get()
  82. >>> print(author.screen_name)
  83. Margaret Smith (Maggie)
  84. ``Greatest``
  85. ============
  86. .. class:: Greatest(*expressions, **extra)
  87. Accepts a list of at least two field names or expressions and returns the
  88. greatest value. Each argument must be of a similar type, so mixing text and
  89. numbers will result in a database error.
  90. Usage example::
  91. class Blog(models.Model):
  92. body = models.TextField()
  93. modified = models.DateTimeField(auto_now=True)
  94. class Comment(models.Model):
  95. body = models.TextField()
  96. modified = models.DateTimeField(auto_now=True)
  97. blog = models.ForeignKey(Blog, on_delete=models.CASCADE)
  98. >>> from django.db.models.functions import Greatest
  99. >>> blog = Blog.objects.create(body='Greatest is the best.')
  100. >>> comment = Comment.objects.create(body='No, Least is better.', blog=blog)
  101. >>> comments = Comment.objects.annotate(last_updated=Greatest('modified', 'blog__modified'))
  102. >>> annotated_comment = comments.get()
  103. ``annotated_comment.last_updated`` will be the most recent of ``blog.modified``
  104. and ``comment.modified``.
  105. .. warning::
  106. The behavior of ``Greatest`` when one or more expression may be ``null``
  107. varies between databases:
  108. - PostgreSQL: ``Greatest`` will return the largest non-null expression,
  109. or ``null`` if all expressions are ``null``.
  110. - SQLite, Oracle, and MySQL: If any expression is ``null``, ``Greatest``
  111. will return ``null``.
  112. The PostgreSQL behavior can be emulated using ``Coalesce`` if you know
  113. a sensible minimum value to provide as a default.
  114. ``Least``
  115. =========
  116. .. class:: Least(*expressions, **extra)
  117. Accepts a list of at least two field names or expressions and returns the
  118. least value. Each argument must be of a similar type, so mixing text and numbers
  119. will result in a database error.
  120. .. warning::
  121. The behavior of ``Least`` when one or more expression may be ``null``
  122. varies between databases:
  123. - PostgreSQL: ``Least`` will return the smallest non-null expression,
  124. or ``null`` if all expressions are ``null``.
  125. - SQLite, Oracle, and MySQL: If any expression is ``null``, ``Least``
  126. will return ``null``.
  127. The PostgreSQL behavior can be emulated using ``Coalesce`` if you know
  128. a sensible maximum value to provide as a default.
  129. ``Length``
  130. ==========
  131. .. class:: Length(expression, **extra)
  132. Accepts a single text field or expression and returns the number of characters
  133. the value has. If the expression is null, then the length will also be null.
  134. Usage example::
  135. >>> # Get the length of the name and goes_by fields
  136. >>> from django.db.models.functions import Length
  137. >>> Author.objects.create(name='Margaret Smith')
  138. >>> author = Author.objects.annotate(
  139. ... name_length=Length('name'),
  140. ... goes_by_length=Length('goes_by')).get()
  141. >>> print(author.name_length, author.goes_by_length)
  142. (14, None)
  143. It can also be registered as a transform. For example::
  144. >>> from django.db.models import CharField
  145. >>> from django.db.models.functions import Length
  146. >>> CharField.register_lookup(Length, 'length')
  147. >>> # Get authors whose name is longer than 7 characters
  148. >>> authors = Author.objects.filter(name__length__gt=7)
  149. ``Lower``
  150. =========
  151. .. class:: Lower(expression, **extra)
  152. Accepts a single text field or expression and returns the lowercase
  153. representation.
  154. It can also be registered as a transform as described in :class:`Length`.
  155. Usage example::
  156. >>> from django.db.models.functions import Lower
  157. >>> Author.objects.create(name='Margaret Smith')
  158. >>> author = Author.objects.annotate(name_lower=Lower('name')).get()
  159. >>> print(author.name_lower)
  160. margaret smith
  161. ``Now``
  162. =======
  163. .. class:: Now()
  164. Returns the database server's current date and time when the query is executed,
  165. typically using the SQL ``CURRENT_TIMESTAMP``.
  166. Usage example::
  167. >>> from django.db.models.functions import Now
  168. >>> Article.objects.filter(published__lte=Now())
  169. <QuerySet [<Article: How to Django>]>
  170. .. admonition:: PostgreSQL considerations
  171. On PostgreSQL, the SQL ``CURRENT_TIMESTAMP`` returns the time that the
  172. current transaction started. Therefore for cross-database compatibility,
  173. ``Now()`` uses ``STATEMENT_TIMESTAMP`` instead. If you need the transaction
  174. timestamp, use :class:`django.contrib.postgres.functions.TransactionNow`.
  175. ``StrIndex``
  176. ============
  177. .. class:: StrIndex(string, substring, **extra)
  178. .. versionadded:: 2.0
  179. Returns a positive integer corresponding to the 1-indexed position of the first
  180. occurrence of ``substring`` inside ``string``, or 0 if ``substring`` is not
  181. found.
  182. Usage example::
  183. >>> from django.db.models import Value as V
  184. >>> from django.db.models.functions import StrIndex
  185. >>> Author.objects.create(name='Margaret Smith')
  186. >>> Author.objects.create(name='Smith, Margaret')
  187. >>> Author.objects.create(name='Margaret Jackson')
  188. >>> authors = Author.objects.annotate(
  189. ... smith_index=StrIndex('name', V('Smith'))
  190. ... ).order_by('smith_index')
  191. >>> authors.first().smith_index
  192. 0
  193. >>> authors = Author.objects.annotate(
  194. ... smith_index=StrIndex('name', V('Smith'))
  195. ... ).filter(smith_index__gt=0)
  196. <QuerySet [<Author: Margaret Smith>, <Author: Smith, Margaret>]>
  197. .. warning::
  198. In MySQL, a database table's :ref:`collation<mysql-collation>` determines
  199. whether string comparisons (such as the ``expression`` and ``substring`` of
  200. this function) are case-sensitive. Comparisons are case-insensitive by
  201. default.
  202. ``Substr``
  203. ==========
  204. .. class:: Substr(expression, pos, length=None, **extra)
  205. Returns a substring of length ``length`` from the field or expression starting
  206. at position ``pos``. The position is 1-indexed, so the position must be greater
  207. than 0. If ``length`` is ``None``, then the rest of the string will be returned.
  208. Usage example::
  209. >>> # Set the alias to the first 5 characters of the name as lowercase
  210. >>> from django.db.models.functions import Substr, Lower
  211. >>> Author.objects.create(name='Margaret Smith')
  212. >>> Author.objects.update(alias=Lower(Substr('name', 1, 5)))
  213. 1
  214. >>> print(Author.objects.get(name='Margaret Smith').alias)
  215. marga
  216. ``Upper``
  217. =========
  218. .. class:: Upper(expression, **extra)
  219. Accepts a single text field or expression and returns the uppercase
  220. representation.
  221. It can also be registered as a transform as described in :class:`Length`.
  222. Usage example::
  223. >>> from django.db.models.functions import Upper
  224. >>> Author.objects.create(name='Margaret Smith')
  225. >>> author = Author.objects.annotate(name_upper=Upper('name')).get()
  226. >>> print(author.name_upper)
  227. MARGARET SMITH
  228. Date Functions
  229. ==============
  230. .. module:: django.db.models.functions.datetime
  231. We'll be using the following model in examples of each function::
  232. class Experiment(models.Model):
  233. start_datetime = models.DateTimeField()
  234. start_date = models.DateField(null=True, blank=True)
  235. start_time = models.TimeField(null=True, blank=True)
  236. end_datetime = models.DateTimeField(null=True, blank=True)
  237. end_date = models.DateField(null=True, blank=True)
  238. end_time = models.TimeField(null=True, blank=True)
  239. ``Extract``
  240. -----------
  241. .. class:: Extract(expression, lookup_name=None, tzinfo=None, **extra)
  242. Extracts a component of a date as a number.
  243. Takes an ``expression`` representing a ``DateField``, ``DateTimeField``,
  244. ``TimeField``, or ``DurationField`` and a ``lookup_name``, and returns the part
  245. of the date referenced by ``lookup_name`` as an ``IntegerField``.
  246. Django usually uses the databases' extract function, so you may use any
  247. ``lookup_name`` that your database supports. A ``tzinfo`` subclass, usually
  248. provided by ``pytz``, can be passed to extract a value in a specific timezone.
  249. .. versionchanged:: 2.0
  250. Support for ``DurationField`` was added.
  251. Given the datetime ``2015-06-15 23:30:01.000321+00:00``, the built-in
  252. ``lookup_name``\s return:
  253. * "year": 2015
  254. * "quarter": 2
  255. * "month": 6
  256. * "day": 15
  257. * "week": 25
  258. * "week_day": 2
  259. * "hour": 23
  260. * "minute": 30
  261. * "second": 1
  262. If a different timezone like ``Australia/Melbourne`` is active in Django, then
  263. the datetime is converted to the timezone before the value is extracted. The
  264. timezone offset for Melbourne in the example date above is +10:00. The values
  265. returned when this timezone is active will be the same as above except for:
  266. * "day": 16
  267. * "week_day": 3
  268. * "hour": 9
  269. .. admonition:: ``week_day`` values
  270. The ``week_day`` ``lookup_type`` is calculated differently from most
  271. databases and from Python's standard functions. This function will return
  272. ``1`` for Sunday, ``2`` for Monday, through ``7`` for Saturday.
  273. The equivalent calculation in Python is::
  274. >>> from datetime import datetime
  275. >>> dt = datetime(2015, 6, 15)
  276. >>> (dt.isoweekday() % 7) + 1
  277. 2
  278. .. admonition:: ``week`` values
  279. The ``week`` ``lookup_type`` is calculated based on `ISO-8601
  280. <https://en.wikipedia.org/wiki/ISO-8601>`_, i.e.,
  281. a week starts on a Monday. The first week is the one with the majority
  282. of the days, i.e., a week that starts on or before Thursday. The value
  283. returned is in the range 1 to 52 or 53.
  284. Each ``lookup_name`` above has a corresponding ``Extract`` subclass (listed
  285. below) that should typically be used instead of the more verbose equivalent,
  286. e.g. use ``ExtractYear(...)`` rather than ``Extract(..., lookup_name='year')``.
  287. Usage example::
  288. >>> from datetime import datetime
  289. >>> from django.db.models.functions import Extract
  290. >>> start = datetime(2015, 6, 15)
  291. >>> end = datetime(2015, 7, 2)
  292. >>> Experiment.objects.create(
  293. ... start_datetime=start, start_date=start.date(),
  294. ... end_datetime=end, end_date=end.date())
  295. >>> # Add the experiment start year as a field in the QuerySet.
  296. >>> experiment = Experiment.objects.annotate(
  297. ... start_year=Extract('start_datetime', 'year')).get()
  298. >>> experiment.start_year
  299. 2015
  300. >>> # How many experiments completed in the same year in which they started?
  301. >>> Experiment.objects.filter(
  302. ... start_datetime__year=Extract('end_datetime', 'year')).count()
  303. 1
  304. ``DateField`` extracts
  305. ~~~~~~~~~~~~~~~~~~~~~~
  306. .. class:: ExtractYear(expression, tzinfo=None, **extra)
  307. .. attribute:: lookup_name = 'year'
  308. .. class:: ExtractMonth(expression, tzinfo=None, **extra)
  309. .. attribute:: lookup_name = 'month'
  310. .. class:: ExtractDay(expression, tzinfo=None, **extra)
  311. .. attribute:: lookup_name = 'day'
  312. .. class:: ExtractWeekDay(expression, tzinfo=None, **extra)
  313. .. attribute:: lookup_name = 'week_day'
  314. .. class:: ExtractWeek(expression, tzinfo=None, **extra)
  315. .. versionadded:: 1.11
  316. .. attribute:: lookup_name = 'week'
  317. .. class:: ExtractQuarter(expression, tzinfo=None, **extra)
  318. .. versionadded:: 2.0
  319. .. attribute:: lookup_name = 'quarter'
  320. These are logically equivalent to ``Extract('date_field', lookup_name)``. Each
  321. class is also a ``Transform`` registered on ``DateField`` and ``DateTimeField``
  322. as ``__(lookup_name)``, e.g. ``__year``.
  323. Since ``DateField``\s don't have a time component, only ``Extract`` subclasses
  324. that deal with date-parts can be used with ``DateField``::
  325. >>> from datetime import datetime
  326. >>> from django.utils import timezone
  327. >>> from django.db.models.functions import (
  328. ... ExtractDay, ExtractMonth, ExtractQuarter, ExtractWeek,
  329. ... ExtractWeekDay, ExtractYear,
  330. ... )
  331. >>> start_2015 = datetime(2015, 6, 15, 23, 30, 1, tzinfo=timezone.utc)
  332. >>> end_2015 = datetime(2015, 6, 16, 13, 11, 27, tzinfo=timezone.utc)
  333. >>> Experiment.objects.create(
  334. ... start_datetime=start_2015, start_date=start_2015.date(),
  335. ... end_datetime=end_2015, end_date=end_2015.date())
  336. >>> Experiment.objects.annotate(
  337. ... year=ExtractYear('start_date'),
  338. ... quarter=ExtractQuarter('start_date'),
  339. ... month=ExtractMonth('start_date'),
  340. ... week=ExtractWeek('start_date'),
  341. ... day=ExtractDay('start_date'),
  342. ... weekday=ExtractWeekDay('start_date'),
  343. ... ).values('year', 'quarter', 'month', 'week', 'day', 'weekday').get(
  344. ... end_date__year=ExtractYear('start_date'),
  345. ... )
  346. {'year': 2015, 'quarter': 2, 'month': 6, 'week': 25, 'day': 15, 'weekday': 2}
  347. ``DateTimeField`` extracts
  348. ~~~~~~~~~~~~~~~~~~~~~~~~~~
  349. In addition to the following, all extracts for ``DateField`` listed above may
  350. also be used on ``DateTimeField``\s .
  351. .. class:: ExtractHour(expression, tzinfo=None, **extra)
  352. .. attribute:: lookup_name = 'hour'
  353. .. class:: ExtractMinute(expression, tzinfo=None, **extra)
  354. .. attribute:: lookup_name = 'minute'
  355. .. class:: ExtractSecond(expression, tzinfo=None, **extra)
  356. .. attribute:: lookup_name = 'second'
  357. These are logically equivalent to ``Extract('datetime_field', lookup_name)``.
  358. Each class is also a ``Transform`` registered on ``DateTimeField`` as
  359. ``__(lookup_name)``, e.g. ``__minute``.
  360. ``DateTimeField`` examples::
  361. >>> from datetime import datetime
  362. >>> from django.utils import timezone
  363. >>> from django.db.models.functions import (
  364. ... ExtractDay, ExtractHour, ExtractMinute, ExtractMonth,
  365. ... ExtractQuarter, ExtractSecond, ExtractWeek, ExtractWeekDay,
  366. ... ExtractYear,
  367. ... )
  368. >>> start_2015 = datetime(2015, 6, 15, 23, 30, 1, tzinfo=timezone.utc)
  369. >>> end_2015 = datetime(2015, 6, 16, 13, 11, 27, tzinfo=timezone.utc)
  370. >>> Experiment.objects.create(
  371. ... start_datetime=start_2015, start_date=start_2015.date(),
  372. ... end_datetime=end_2015, end_date=end_2015.date())
  373. >>> Experiment.objects.annotate(
  374. ... year=ExtractYear('start_datetime'),
  375. ... quarter=ExtractQuarter('start_datetime'),
  376. ... month=ExtractMonth('start_datetime'),
  377. ... week=ExtractWeek('start_datetime'),
  378. ... day=ExtractDay('start_datetime'),
  379. ... weekday=ExtractWeekDay('start_datetime'),
  380. ... hour=ExtractHour('start_datetime'),
  381. ... minute=ExtractMinute('start_datetime'),
  382. ... second=ExtractSecond('start_datetime'),
  383. ... ).values(
  384. ... 'year', 'month', 'week', 'day', 'weekday', 'hour', 'minute', 'second',
  385. ... ).get(end_datetime__year=ExtractYear('start_datetime'))
  386. {'year': 2015, 'quarter': 2, 'month': 6, 'week': 25, 'day': 15, 'weekday': 2,
  387. 'hour': 23, 'minute': 30, 'second': 1}
  388. When :setting:`USE_TZ` is ``True`` then datetimes are stored in the database
  389. in UTC. If a different timezone is active in Django, the datetime is converted
  390. to that timezone before the value is extracted. The example below converts to
  391. the Melbourne timezone (UTC +10:00), which changes the day, weekday, and hour
  392. values that are returned::
  393. >>> import pytz
  394. >>> tzinfo = pytz.timezone('Australia/Melbourne') # UTC+10:00
  395. >>> with timezone.override(tzinfo):
  396. ... Experiment.objects.annotate(
  397. ... day=ExtractDay('start_datetime'),
  398. ... weekday=ExtractWeekDay('start_datetime'),
  399. ... hour=ExtractHour('start_datetime'),
  400. ... ).values('day', 'weekday', 'hour').get(
  401. ... end_datetime__year=ExtractYear('start_datetime'),
  402. ... )
  403. {'day': 16, 'weekday': 3, 'hour': 9}
  404. Explicitly passing the timezone to the ``Extract`` function behaves in the same
  405. way, and takes priority over an active timezone::
  406. >>> import pytz
  407. >>> tzinfo = pytz.timezone('Australia/Melbourne')
  408. >>> Experiment.objects.annotate(
  409. ... day=ExtractDay('start_datetime', tzinfo=melb),
  410. ... weekday=ExtractWeekDay('start_datetime', tzinfo=melb),
  411. ... hour=ExtractHour('start_datetime', tzinfo=melb),
  412. ... ).values('day', 'weekday', 'hour').get(
  413. ... end_datetime__year=ExtractYear('start_datetime'),
  414. ... )
  415. {'day': 16, 'weekday': 3, 'hour': 9}
  416. ``Trunc``
  417. ---------
  418. .. class:: Trunc(expression, kind, output_field=None, tzinfo=None, **extra)
  419. Truncates a date up to a significant component.
  420. When you only care if something happened in a particular year, hour, or day,
  421. but not the exact second, then ``Trunc`` (and its subclasses) can be useful to
  422. filter or aggregate your data. For example, you can use ``Trunc`` to calculate
  423. the number of sales per day.
  424. ``Trunc`` takes a single ``expression``, representing a ``DateField``,
  425. ``TimeField``, or ``DateTimeField``, a ``kind`` representing a date or time
  426. part, and an ``output_field`` that's either ``DateTimeField()``,
  427. ``TimeField()``, or ``DateField()``. It returns a datetime, date, or time
  428. depending on ``output_field``, with fields up to ``kind`` set to their minimum
  429. value. If ``output_field`` is omitted, it will default to the ``output_field``
  430. of ``expression``. A ``tzinfo`` subclass, usually provided by ``pytz``, can be
  431. passed to truncate a value in a specific timezone.
  432. Given the datetime ``2015-06-15 14:30:50.000321+00:00``, the built-in ``kind``\s
  433. return:
  434. * "year": 2015-01-01 00:00:00+00:00
  435. * "quarter": 2015-04-01 00:00:00+00:00
  436. * "month": 2015-06-01 00:00:00+00:00
  437. * "day": 2015-06-15 00:00:00+00:00
  438. * "hour": 2015-06-15 14:00:00+00:00
  439. * "minute": 2015-06-15 14:30:00+00:00
  440. * "second": 2015-06-15 14:30:50+00:00
  441. If a different timezone like ``Australia/Melbourne`` is active in Django, then
  442. the datetime is converted to the new timezone before the value is truncated.
  443. The timezone offset for Melbourne in the example date above is +10:00. The
  444. values returned when this timezone is active will be:
  445. * "year": 2015-01-01 00:00:00+11:00
  446. * "quarter": 2015-04-01 00:00:00+10:00
  447. * "month": 2015-06-01 00:00:00+10:00
  448. * "day": 2015-06-16 00:00:00+10:00
  449. * "hour": 2015-06-16 00:00:00+10:00
  450. * "minute": 2015-06-16 00:30:00+10:00
  451. * "second": 2015-06-16 00:30:50+10:00
  452. The year has an offset of +11:00 because the result transitioned into daylight
  453. saving time.
  454. Each ``kind`` above has a corresponding ``Trunc`` subclass (listed below) that
  455. should typically be used instead of the more verbose equivalent,
  456. e.g. use ``TruncYear(...)`` rather than ``Trunc(..., kind='year')``.
  457. The subclasses are all defined as transforms, but they aren't registered with
  458. any fields, because the obvious lookup names are already reserved by the
  459. ``Extract`` subclasses.
  460. Usage example::
  461. >>> from datetime import datetime
  462. >>> from django.db.models import Count, DateTimeField
  463. >>> from django.db.models.functions import Trunc
  464. >>> Experiment.objects.create(start_datetime=datetime(2015, 6, 15, 14, 30, 50, 321))
  465. >>> Experiment.objects.create(start_datetime=datetime(2015, 6, 15, 14, 40, 2, 123))
  466. >>> Experiment.objects.create(start_datetime=datetime(2015, 12, 25, 10, 5, 27, 999))
  467. >>> experiments_per_day = Experiment.objects.annotate(
  468. ... start_day=Trunc('start_datetime', 'day', output_field=DateTimeField())
  469. ... ).values('start_day').annotate(experiments=Count('id'))
  470. >>> for exp in experiments_per_day:
  471. ... print(exp['start_day'], exp['experiments'])
  472. ...
  473. 2015-06-15 00:00:00 2
  474. 2015-12-25 00:00:00 1
  475. >>> experiments = Experiment.objects.annotate(
  476. ... start_day=Trunc('start_datetime', 'day', output_field=DateTimeField())
  477. ... ).filter(start_day=datetime(2015, 6, 15))
  478. >>> for exp in experiments:
  479. ... print(exp.start_datetime)
  480. ...
  481. 2015-06-15 14:30:50.000321
  482. 2015-06-15 14:40:02.000123
  483. ``DateField`` truncation
  484. ~~~~~~~~~~~~~~~~~~~~~~~~
  485. .. class:: TruncYear(expression, output_field=None, tzinfo=None, **extra)
  486. .. attribute:: kind = 'year'
  487. .. class:: TruncMonth(expression, output_field=None, tzinfo=None, **extra)
  488. .. attribute:: kind = 'month'
  489. .. class:: TruncQuarter(expression, output_field=None, tzinfo=None, **extra)
  490. .. versionadded:: 2.0
  491. .. attribute:: kind = 'quarter'
  492. These are logically equivalent to ``Trunc('date_field', kind)``. They truncate
  493. all parts of the date up to ``kind`` which allows grouping or filtering dates
  494. with less precision. ``expression`` can have an ``output_field`` of either
  495. ``DateField`` or ``DateTimeField``.
  496. Since ``DateField``\s don't have a time component, only ``Trunc`` subclasses
  497. that deal with date-parts can be used with ``DateField``::
  498. >>> from datetime import datetime
  499. >>> from django.db.models import Count
  500. >>> from django.db.models.functions import TruncMonth, TruncYear
  501. >>> from django.utils import timezone
  502. >>> start1 = datetime(2014, 6, 15, 14, 30, 50, 321, tzinfo=timezone.utc)
  503. >>> start2 = datetime(2015, 6, 15, 14, 40, 2, 123, tzinfo=timezone.utc)
  504. >>> start3 = datetime(2015, 12, 31, 17, 5, 27, 999, tzinfo=timezone.utc)
  505. >>> Experiment.objects.create(start_datetime=start1, start_date=start1.date())
  506. >>> Experiment.objects.create(start_datetime=start2, start_date=start2.date())
  507. >>> Experiment.objects.create(start_datetime=start3, start_date=start3.date())
  508. >>> experiments_per_year = Experiment.objects.annotate(
  509. ... year=TruncYear('start_date')).values('year').annotate(
  510. ... experiments=Count('id'))
  511. >>> for exp in experiments_per_year:
  512. ... print(exp['year'], exp['experiments'])
  513. ...
  514. 2014-01-01 1
  515. 2015-01-01 2
  516. >>> import pytz
  517. >>> melb = pytz.timezone('Australia/Melbourne')
  518. >>> experiments_per_month = Experiment.objects.annotate(
  519. ... month=TruncMonth('start_datetime', tzinfo=melb)).values('month').annotate(
  520. ... experiments=Count('id'))
  521. >>> for exp in experiments_per_month:
  522. ... print(exp['month'], exp['experiments'])
  523. ...
  524. 2015-06-01 00:00:00+10:00 1
  525. 2016-01-01 00:00:00+11:00 1
  526. 2014-06-01 00:00:00+10:00 1
  527. ``TimeField`` truncation
  528. ~~~~~~~~~~~~~~~~~~~~~~~~
  529. .. versionadded:: 1.11
  530. .. class:: TruncHour(expression, output_field=None, tzinfo=None, **extra)
  531. .. attribute:: kind = 'hour'
  532. .. class:: TruncMinute(expression, output_field=None, tzinfo=None, **extra)
  533. .. attribute:: kind = 'minute'
  534. .. class:: TruncSecond(expression, output_field=None, tzinfo=None, **extra)
  535. .. attribute:: kind = 'second'
  536. These are logically equivalent to ``Trunc('time_field', kind)``. They truncate
  537. all parts of the time up to ``kind`` which allows grouping or filtering times
  538. with less precision. ``expression`` can have an ``output_field`` of either
  539. ``TimeField`` or ``DateTimeField``.
  540. Since ``TimeField``\s don't have a date component, only ``Trunc`` subclasses
  541. that deal with time-parts can be used with ``TimeField``::
  542. >>> from datetime import datetime
  543. >>> from django.db.models import Count, TimeField
  544. >>> from django.db.models.functions import TruncHour
  545. >>> from django.utils import timezone
  546. >>> start1 = datetime(2014, 6, 15, 14, 30, 50, 321, tzinfo=timezone.utc)
  547. >>> start2 = datetime(2014, 6, 15, 14, 40, 2, 123, tzinfo=timezone.utc)
  548. >>> start3 = datetime(2015, 12, 31, 17, 5, 27, 999, tzinfo=timezone.utc)
  549. >>> Experiment.objects.create(start_datetime=start1, start_time=start1.time())
  550. >>> Experiment.objects.create(start_datetime=start2, start_time=start2.time())
  551. >>> Experiment.objects.create(start_datetime=start3, start_time=start3.time())
  552. >>> experiments_per_hour = Experiment.objects.annotate(
  553. ... hour=TruncHour('start_datetime', output_field=TimeField()),
  554. ... ).values('hour').annotate(experiments=Count('id'))
  555. >>> for exp in experiments_per_hour:
  556. ... print(exp['hour'], exp['experiments'])
  557. ...
  558. 14:00:00 2
  559. 17:00:00 1
  560. >>> import pytz
  561. >>> melb = pytz.timezone('Australia/Melbourne')
  562. >>> experiments_per_hour = Experiment.objects.annotate(
  563. ... hour=TruncHour('start_datetime', tzinfo=melb),
  564. ... ).values('hour').annotate(experiments=Count('id'))
  565. >>> for exp in experiments_per_hour:
  566. ... print(exp['hour'], exp['experiments'])
  567. ...
  568. 2014-06-16 00:00:00+10:00 2
  569. 2016-01-01 04:00:00+11:00 1
  570. ``DateTimeField`` truncation
  571. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  572. .. class:: TruncDate(expression, **extra)
  573. .. attribute:: lookup_name = 'date'
  574. .. attribute:: output_field = DateField()
  575. ``TruncDate`` casts ``expression`` to a date rather than using the built-in SQL
  576. truncate function. It's also registered as a transform on ``DateTimeField`` as
  577. ``__date``.
  578. .. class:: TruncTime(expression, **extra)
  579. .. versionadded:: 1.11
  580. .. attribute:: lookup_name = 'time'
  581. .. attribute:: output_field = TimeField()
  582. ``TruncTime`` casts ``expression`` to a time rather than using the built-in SQL
  583. truncate function. It's also registered as a transform on ``DateTimeField`` as
  584. ``__time``.
  585. .. class:: TruncDay(expression, output_field=None, tzinfo=None, **extra)
  586. .. attribute:: kind = 'day'
  587. .. class:: TruncHour(expression, output_field=None, tzinfo=None, **extra)
  588. .. attribute:: kind = 'hour'
  589. .. class:: TruncMinute(expression, output_field=None, tzinfo=None, **extra)
  590. .. attribute:: kind = 'minute'
  591. .. class:: TruncSecond(expression, output_field=None, tzinfo=None, **extra)
  592. .. attribute:: kind = 'second'
  593. These are logically equivalent to ``Trunc('datetime_field', kind)``. They
  594. truncate all parts of the date up to ``kind`` and allow grouping or filtering
  595. datetimes with less precision. ``expression`` must have an ``output_field`` of
  596. ``DateTimeField``.
  597. Usage example::
  598. >>> from datetime import date, datetime
  599. >>> from django.db.models import Count
  600. >>> from django.db.models.functions import (
  601. ... TruncDate, TruncDay, TruncHour, TruncMinute, TruncSecond,
  602. ... )
  603. >>> from django.utils import timezone
  604. >>> import pytz
  605. >>> start1 = datetime(2014, 6, 15, 14, 30, 50, 321, tzinfo=timezone.utc)
  606. >>> Experiment.objects.create(start_datetime=start1, start_date=start1.date())
  607. >>> melb = pytz.timezone('Australia/Melbourne')
  608. >>> Experiment.objects.annotate(
  609. ... date=TruncDate('start_datetime'),
  610. ... day=TruncDay('start_datetime', tzinfo=melb),
  611. ... hour=TruncHour('start_datetime', tzinfo=melb),
  612. ... minute=TruncMinute('start_datetime'),
  613. ... second=TruncSecond('start_datetime'),
  614. ... ).values('date', 'day', 'hour', 'minute', 'second').get()
  615. {'date': datetime.date(2014, 6, 15),
  616. 'day': datetime.datetime(2014, 6, 16, 0, 0, tzinfo=<DstTzInfo 'Australia/Melbourne' AEST+10:00:00 STD>),
  617. 'hour': datetime.datetime(2014, 6, 16, 0, 0, tzinfo=<DstTzInfo 'Australia/Melbourne' AEST+10:00:00 STD>),
  618. 'minute': 'minute': datetime.datetime(2014, 6, 15, 14, 30, tzinfo=<UTC>),
  619. 'second': datetime.datetime(2014, 6, 15, 14, 30, 50, tzinfo=<UTC>)
  620. }