database-functions.txt 30 KB

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