summaryrefslogtreecommitdiff
path: root/docs/ref
diff options
context:
space:
mode:
authorSimon Charette <charette.s@gmail.com>2016-06-18 23:38:24 -0400
committerSimon Charette <charette.s@gmail.com>2016-07-08 12:35:34 -0400
commit082c52dbedd76c312cebf3b23e04c449a94c20b6 (patch)
tree0ae566d52a61ac42f5a918931684fd3779f045af /docs/ref
parent90468079ec6f72a1b8b6a908d81d3201a3204b24 (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.txt72
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
~~~~~~~~~~~~~~~~~~~~~~~~~~~~