mirror of
https://github.com/django/django.git
synced 2025-10-29 16:46:11 +00:00
Fixed #17260 -- Added time zone aware aggregation and lookups.
Thanks Carl Meyer for the review. Squashed commit of the following: commit4f290bdb60Author: Aymeric Augustin <aymeric.augustin@m4x.org> Date: Wed Feb 13 21:21:30 2013 +0100 Used '0:00' instead of 'UTC' which doesn't always exist in Oracle. Thanks Ian Kelly for the suggestion. commit01b6366f3cAuthor: Aymeric Augustin <aymeric.augustin@m4x.org> Date: Wed Feb 13 13:38:43 2013 +0100 Made tzname a parameter of datetime_extract/trunc_sql. This is required to work around a bug in Oracle. commit924a144ef8Author: Aymeric Augustin <aymeric.augustin@m4x.org> Date: Wed Feb 13 14:47:44 2013 +0100 Added support for parameters in SELECT clauses. commitb4351d2890Author: Aymeric Augustin <aymeric.augustin@m4x.org> Date: Mon Feb 11 22:30:22 2013 +0100 Documented backwards incompatibilities in the two previous commits. commit91ef84713cAuthor: Aymeric Augustin <aymeric.augustin@m4x.org> Date: Mon Feb 11 09:42:31 2013 +0100 Used QuerySet.datetimes for the admin's date_hierarchy. commit0d0de288a5Author: Aymeric Augustin <aymeric.augustin@m4x.org> Date: Mon Feb 11 09:29:38 2013 +0100 Used QuerySet.datetimes in date-based generic views. commit9c0859ff7cAuthor: Aymeric Augustin <aymeric.augustin@m4x.org> Date: Sun Feb 10 21:43:25 2013 +0100 Implemented QuerySet.datetimes on Oracle. commit68ab511a4fAuthor: Aymeric Augustin <aymeric.augustin@m4x.org> Date: Sun Feb 10 21:43:14 2013 +0100 Implemented QuerySet.datetimes on MySQL. commit22d52681d3Author: Aymeric Augustin <aymeric.augustin@m4x.org> Date: Sun Feb 10 21:42:29 2013 +0100 Implemented QuerySet.datetimes on SQLite. commitf6800fd04cAuthor: Aymeric Augustin <aymeric.augustin@m4x.org> Date: Sun Feb 10 21:43:03 2013 +0100 Implemented QuerySet.datetimes on PostgreSQL. commit0c829c23f4Author: Aymeric Augustin <aymeric.augustin@m4x.org> Date: Sun Feb 10 21:41:08 2013 +0100 Added datetime-handling infrastructure in the ORM layers. commit104d82a777Author: Aymeric Augustin <aymeric.augustin@m4x.org> Date: Mon Feb 11 10:05:55 2013 +0100 Updated null_queries tests to avoid clashing with the __second lookup. commitc01bbb3235Author: Aymeric Augustin <aymeric.augustin@m4x.org> Date: Sun Feb 10 23:07:41 2013 +0100 Updated tests of .dates(). Replaced .dates() by .datetimes() for DateTimeFields. Replaced dates with datetimes in the expected output for DateFields. commit50fb7a5246Author: Aymeric Augustin <aymeric.augustin@m4x.org> Date: Sun Feb 10 21:40:09 2013 +0100 Updated and added tests for QuerySet.datetimes. commita8451a5004Author: Aymeric Augustin <aymeric.augustin@m4x.org> Date: Sun Feb 10 22:34:46 2013 +0100 Documented the new time lookups and updated the date lookups. commit29413eab2bAuthor: Aymeric Augustin <aymeric.augustin@m4x.org> Date: Sun Feb 10 16:15:49 2013 +0100 Documented QuerySet.datetimes and updated QuerySet.dates.
This commit is contained in:
@@ -7,6 +7,7 @@ import itertools
|
||||
import sys
|
||||
import warnings
|
||||
|
||||
from django.conf import settings
|
||||
from django.core import exceptions
|
||||
from django.db import connections, router, transaction, IntegrityError
|
||||
from django.db.models.constants import LOOKUP_SEP
|
||||
@@ -17,6 +18,7 @@ from django.db.models.deletion import Collector
|
||||
from django.db.models import sql
|
||||
from django.utils.functional import partition
|
||||
from django.utils import six
|
||||
from django.utils import timezone
|
||||
|
||||
# Used to control how many objects are worked with at once in some cases (e.g.
|
||||
# when deleting objects).
|
||||
@@ -629,16 +631,33 @@ class QuerySet(object):
|
||||
|
||||
def dates(self, field_name, kind, order='ASC'):
|
||||
"""
|
||||
Returns a list of datetime objects representing all available dates for
|
||||
Returns a list of date objects representing all available dates for
|
||||
the given field_name, scoped to 'kind'.
|
||||
"""
|
||||
assert kind in ("month", "year", "day"), \
|
||||
assert kind in ("year", "month", "day"), \
|
||||
"'kind' must be one of 'year', 'month' or 'day'."
|
||||
assert order in ('ASC', 'DESC'), \
|
||||
"'order' must be either 'ASC' or 'DESC'."
|
||||
return self._clone(klass=DateQuerySet, setup=True,
|
||||
_field_name=field_name, _kind=kind, _order=order)
|
||||
|
||||
def datetimes(self, field_name, kind, order='ASC', tzinfo=None):
|
||||
"""
|
||||
Returns a list of datetime objects representing all available
|
||||
datetimes for the given field_name, scoped to 'kind'.
|
||||
"""
|
||||
assert kind in ("year", "month", "day", "hour", "minute", "second"), \
|
||||
"'kind' must be one of 'year', 'month', 'day', 'hour', 'minute' or 'second'."
|
||||
assert order in ('ASC', 'DESC'), \
|
||||
"'order' must be either 'ASC' or 'DESC'."
|
||||
if settings.USE_TZ:
|
||||
if tzinfo is None:
|
||||
tzinfo = timezone.get_current_timezone()
|
||||
else:
|
||||
tzinfo = None
|
||||
return self._clone(klass=DateTimeQuerySet, setup=True,
|
||||
_field_name=field_name, _kind=kind, _order=order, _tzinfo=tzinfo)
|
||||
|
||||
def none(self):
|
||||
"""
|
||||
Returns an empty QuerySet.
|
||||
@@ -1187,7 +1206,7 @@ class DateQuerySet(QuerySet):
|
||||
self.query.clear_deferred_loading()
|
||||
self.query = self.query.clone(klass=sql.DateQuery, setup=True)
|
||||
self.query.select = []
|
||||
self.query.add_date_select(self._field_name, self._kind, self._order)
|
||||
self.query.add_select(self._field_name, self._kind, self._order)
|
||||
|
||||
def _clone(self, klass=None, setup=False, **kwargs):
|
||||
c = super(DateQuerySet, self)._clone(klass, False, **kwargs)
|
||||
@@ -1198,6 +1217,32 @@ class DateQuerySet(QuerySet):
|
||||
return c
|
||||
|
||||
|
||||
class DateTimeQuerySet(QuerySet):
|
||||
def iterator(self):
|
||||
return self.query.get_compiler(self.db).results_iter()
|
||||
|
||||
def _setup_query(self):
|
||||
"""
|
||||
Sets up any special features of the query attribute.
|
||||
|
||||
Called by the _clone() method after initializing the rest of the
|
||||
instance.
|
||||
"""
|
||||
self.query.clear_deferred_loading()
|
||||
self.query = self.query.clone(klass=sql.DateTimeQuery, setup=True, tzinfo=self._tzinfo)
|
||||
self.query.select = []
|
||||
self.query.add_select(self._field_name, self._kind, self._order)
|
||||
|
||||
def _clone(self, klass=None, setup=False, **kwargs):
|
||||
c = super(DateTimeQuerySet, self)._clone(klass, False, **kwargs)
|
||||
c._field_name = self._field_name
|
||||
c._kind = self._kind
|
||||
c._tzinfo = self._tzinfo
|
||||
if setup and hasattr(c, '_setup_query'):
|
||||
c._setup_query()
|
||||
return c
|
||||
|
||||
|
||||
def get_klass_info(klass, max_depth=0, cur_depth=0, requested=None,
|
||||
only_load=None, from_parent=None):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user