Fixed #28649 -- Added ExtractIsoYear database function and iso_year lookup.

This commit is contained in:
Sigurd Ljødal 2017-09-28 22:28:48 +02:00 committed by Tim Graham
parent c832885a3e
commit 3e09b37f80
10 changed files with 161 additions and 46 deletions

View file

@ -182,6 +182,7 @@ Given the datetime ``2015-06-15 23:30:01.000321+00:00``, the built-in
``lookup_name``\s return:
* "year": 2015
* "iso_year": 2015
* "quarter": 2
* "month": 6
* "day": 15
@ -252,6 +253,14 @@ Usage example::
.. attribute:: lookup_name = 'year'
.. class:: ExtractIsoYear(expression, tzinfo=None, **extra)
.. versionadded:: 2.2
Returns the ISO-8601 week-numbering year.
.. attribute:: lookup_name = 'iso_year'
.. class:: ExtractMonth(expression, tzinfo=None, **extra)
.. attribute:: lookup_name = 'month'
@ -283,7 +292,7 @@ that deal with date-parts can be used with ``DateField``::
>>> from django.utils import timezone
>>> from django.db.models.functions import (
... ExtractDay, ExtractMonth, ExtractQuarter, ExtractWeek,
... ExtractWeekDay, ExtractYear,
... ExtractWeekDay, ExtractIsoYear, 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)
@ -292,15 +301,17 @@ that deal with date-parts can be used with ``DateField``::
... end_datetime=end_2015, end_date=end_2015.date())
>>> Experiment.objects.annotate(
... year=ExtractYear('start_date'),
... isoyear=ExtractIsoYear('start_date'),
... quarter=ExtractQuarter('start_date'),
... month=ExtractMonth('start_date'),
... week=ExtractWeek('start_date'),
... day=ExtractDay('start_date'),
... weekday=ExtractWeekDay('start_date'),
... ).values('year', 'quarter', 'month', 'week', 'day', 'weekday').get(
... ).values('year', 'isoyear', 'quarter', 'month', 'week', 'day', 'weekday').get(
... end_date__year=ExtractYear('start_date'),
... )
{'year': 2015, 'quarter': 2, 'month': 6, 'week': 25, 'day': 15, 'weekday': 2}
{'year': 2015, 'isoyear': 2015, 'quarter': 2, 'month': 6, 'week': 25,
'day': 15, 'weekday': 2}
``DateTimeField`` extracts
~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -340,6 +351,7 @@ Each class is also a ``Transform`` registered on ``DateTimeField`` as
... end_datetime=end_2015, end_date=end_2015.date())
>>> Experiment.objects.annotate(
... year=ExtractYear('start_datetime'),
... isoyear=ExtractIsoYear('start_datetime'),
... quarter=ExtractQuarter('start_datetime'),
... month=ExtractMonth('start_datetime'),
... week=ExtractWeek('start_datetime'),
@ -349,10 +361,11 @@ Each class is also a ``Transform`` registered on ``DateTimeField`` as
... minute=ExtractMinute('start_datetime'),
... second=ExtractSecond('start_datetime'),
... ).values(
... 'year', 'month', 'week', 'day', 'weekday', 'hour', 'minute', 'second',
... 'year', 'isoyear', 'month', 'week', 'day',
... 'weekday', 'hour', 'minute', 'second',
... ).get(end_datetime__year=ExtractYear('start_datetime'))
{'year': 2015, 'quarter': 2, 'month': 6, 'week': 25, 'day': 15, 'weekday': 2,
'hour': 23, 'minute': 30, 'second': 1}
{'year': 2015, 'isoyear': 2015, 'quarter': 2, 'month': 6, 'week': 25,
'day': 15, 'weekday': 2, 'hour': 23, 'minute': 30, 'second': 1}
When :setting:`USE_TZ` is ``True`` then datetimes are stored in the database
in UTC. If a different timezone is active in Django, the datetime is converted

View file

@ -2927,6 +2927,26 @@ SQL equivalent::
When :setting:`USE_TZ` is ``True``, datetime fields are converted to the
current time zone before filtering.
.. fieldlookup:: iso_year
``iso_year``
~~~~~~~~~~~~
.. versionadded:: 2.2
For date and datetime fields, an exact ISO 8601 week-numbering year match.
Allows chaining additional field lookups. Takes an integer year.
Example::
Entry.objects.filter(pub_date__iso_year=2005)
Entry.objects.filter(pub_date__iso_year__gte=2005)
(The exact SQL syntax varies for each database engine.)
When :setting:`USE_TZ` is ``True``, datetime fields are converted to the
current time zone before filtering.
.. fieldlookup:: month
``month``