diff options
| author | Simon Charette <charette.s@gmail.com> | 2016-06-18 23:38:24 -0400 |
|---|---|---|
| committer | Simon Charette <charette.s@gmail.com> | 2016-07-08 12:35:34 -0400 |
| commit | 082c52dbedd76c312cebf3b23e04c449a94c20b6 (patch) | |
| tree | 0ae566d52a61ac42f5a918931684fd3779f045af /docs/ref | |
| parent | 90468079ec6f72a1b8b6a908d81d3201a3204b24 (diff) | |
Refs #25774, #26348 -- Allowed Trunc functions to operate with time fields.
Thanks Josh for the amazing testing setup and Tim for the review.
Diffstat (limited to 'docs/ref')
| -rw-r--r-- | docs/ref/models/database-functions.txt | 72 |
1 files changed, 65 insertions, 7 deletions
diff --git a/docs/ref/models/database-functions.txt b/docs/ref/models/database-functions.txt index d6c48f966c..20ceadde91 100644 --- a/docs/ref/models/database-functions.txt +++ b/docs/ref/models/database-functions.txt @@ -288,8 +288,10 @@ We'll be using the following model in examples of each function:: 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`` ----------- @@ -500,13 +502,14 @@ but not the exact second, then ``Trunc`` (and its subclasses) can be useful to filter or aggregate your data. For example, you can use ``Trunc`` to calculate the number of sales per day. -``Trunc`` takes a single ``expression``, representing a ``DateField`` or -``DateTimeField``, a ``kind`` representing a date part, and an ``output_field`` -that's either ``DateTimeField()`` or ``DateField()``. It returns a datetime or -date, depending on ``output_field``, with fields up to ``kind`` set to their -minimum value. If ``output_field`` is omitted, it will default to the -``output_field`` of ``expression``. A ``tzinfo`` subclass, usually provided by -``pytz``, can be passed to truncate a value in a specific timezone. +``Trunc`` takes a single ``expression``, representing a ``DateField``, +``TimeField``, or ``DateTimeField``, a ``kind`` representing a date or time +part, and an ``output_field`` that's either ``DateTimeField()``, +``TimeField()``, or ``DateField()``. It returns a datetime, date, or time +depending on ``output_field``, with fields up to ``kind`` set to their minimum +value. If ``output_field`` is omitted, it will default to the ``output_field`` +of ``expression``. A ``tzinfo`` subclass, usually provided by ``pytz``, can be +passed to truncate a value in a specific timezone. Given the datetime ``2015-06-15 14:30:50.000321+00:00``, the built-in ``kind``\s return: @@ -616,6 +619,61 @@ that deal with date-parts can be used with ``DateField``:: 2016-01-01 00:00:00+11:00 1 2014-06-01 00:00:00+10:00 1 +``TimeField`` truncation +~~~~~~~~~~~~~~~~~~~~~~~~ + +.. versionadded:: 1.11 + +.. class:: TruncHour(expression, output_field=None, tzinfo=None, **extra) + + .. attribute:: kind = 'hour' + +.. class:: TruncMinute(expression, output_field=None, tzinfo=None, **extra) + + .. attribute:: kind = 'minute' + +.. class:: TruncSecond(expression, output_field=None, tzinfo=None, **extra) + + .. attribute:: kind = 'second' + +These are logically equivalent to ``Trunc('time_field', kind)``. They truncate +all parts of the time up to ``kind`` which allows grouping or filtering times +with less precision. ``expression`` can have an ``output_field`` of either +``TimeField`` or ``DateTimeField``. + +Since ``TimeField``\s don't have a date component, only ``Trunc`` subclasses +that deal with time-parts can be used with ``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`` truncation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
