mirror of https://github.com/django/django.git
Made tzname a parameter of datetime_extract/trunc_sql.
This is required to work around a bug in Oracle.
This commit is contained in:
parent
924a144ef8
commit
01b6366f3c
|
@ -542,25 +542,20 @@ class BaseDatabaseOperations(object):
|
||||||
"""
|
"""
|
||||||
return "%s"
|
return "%s"
|
||||||
|
|
||||||
def datetime_extract_sql(self, lookup_type, field_name):
|
def datetime_extract_sql(self, lookup_type, field_name, tzname):
|
||||||
"""
|
"""
|
||||||
Given a lookup_type of 'year', 'month', 'day', 'hour', 'minute' or
|
Given a lookup_type of 'year', 'month', 'day', 'hour', 'minute' or
|
||||||
'second', returns the SQL that extracts a value from the given
|
'second', returns the SQL that extracts a value from the given
|
||||||
datetime field field_name.
|
datetime field field_name, and a tuple of parameters.
|
||||||
|
|
||||||
When time zone support is enabled, the SQL should include a '%s'
|
|
||||||
placeholder for the time zone's name.
|
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
def datetime_trunc_sql(self, lookup_type, field_name):
|
def datetime_trunc_sql(self, lookup_type, field_name, tzname):
|
||||||
"""
|
"""
|
||||||
Given a lookup_type of 'year', 'month', 'day', 'hour', 'minute' or
|
Given a lookup_type of 'year', 'month', 'day', 'hour', 'minute' or
|
||||||
'second', returns the SQL that truncates the given datetime field
|
'second', returns the SQL that truncates the given datetime field
|
||||||
field_name to a datetime object with only the given specificity.
|
field_name to a datetime object with only the given specificity, and
|
||||||
|
a tuple of parameters.
|
||||||
When time zone support is enabled, the SQL should include a '%s'
|
|
||||||
placeholder for the time zone's name.
|
|
||||||
"""
|
"""
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
|
@ -225,20 +225,27 @@ class DatabaseOperations(BaseDatabaseOperations):
|
||||||
sql = "CAST(DATE_FORMAT(%s, '%s') AS DATETIME)" % (field_name, format_str)
|
sql = "CAST(DATE_FORMAT(%s, '%s') AS DATETIME)" % (field_name, format_str)
|
||||||
return sql
|
return sql
|
||||||
|
|
||||||
def datetime_extract_sql(self, lookup_type, field_name):
|
def datetime_extract_sql(self, lookup_type, field_name, tzname):
|
||||||
if settings.USE_TZ:
|
if settings.USE_TZ:
|
||||||
field_name = "CONVERT_TZ(%s, 'UTC', %%s)" % field_name
|
field_name = "CONVERT_TZ(%s, 'UTC', %%s)" % field_name
|
||||||
|
params = [tzname]
|
||||||
|
else:
|
||||||
|
params = []
|
||||||
# http://dev.mysql.com/doc/mysql/en/date-and-time-functions.html
|
# http://dev.mysql.com/doc/mysql/en/date-and-time-functions.html
|
||||||
if lookup_type == 'week_day':
|
if lookup_type == 'week_day':
|
||||||
# DAYOFWEEK() returns an integer, 1-7, Sunday=1.
|
# DAYOFWEEK() returns an integer, 1-7, Sunday=1.
|
||||||
# Note: WEEKDAY() returns 0-6, Monday=0.
|
# Note: WEEKDAY() returns 0-6, Monday=0.
|
||||||
return "DAYOFWEEK(%s)" % field_name
|
sql = "DAYOFWEEK(%s)" % field_name
|
||||||
else:
|
else:
|
||||||
return "EXTRACT(%s FROM %s)" % (lookup_type.upper(), field_name)
|
sql = "EXTRACT(%s FROM %s)" % (lookup_type.upper(), field_name)
|
||||||
|
return sql, params
|
||||||
|
|
||||||
def datetime_trunc_sql(self, lookup_type, field_name):
|
def datetime_trunc_sql(self, lookup_type, field_name, tzname):
|
||||||
if settings.USE_TZ:
|
if settings.USE_TZ:
|
||||||
field_name = "CONVERT_TZ(%s, 'UTC', %%s)" % field_name
|
field_name = "CONVERT_TZ(%s, 'UTC', %%s)" % field_name
|
||||||
|
params = [tzname]
|
||||||
|
else:
|
||||||
|
params = []
|
||||||
fields = ['year', 'month', 'day', 'hour', 'minute', 'second']
|
fields = ['year', 'month', 'day', 'hour', 'minute', 'second']
|
||||||
format = ('%%Y-', '%%m', '-%%d', ' %%H:', '%%i', ':%%s') # Use double percents to escape.
|
format = ('%%Y-', '%%m', '-%%d', ' %%H:', '%%i', ':%%s') # Use double percents to escape.
|
||||||
format_def = ('0000-', '01', '-01', ' 00:', '00', ':00')
|
format_def = ('0000-', '01', '-01', ' 00:', '00', ':00')
|
||||||
|
@ -249,7 +256,7 @@ class DatabaseOperations(BaseDatabaseOperations):
|
||||||
else:
|
else:
|
||||||
format_str = ''.join([f for f in format[:i]] + [f for f in format_def[i:]])
|
format_str = ''.join([f for f in format[:i]] + [f for f in format_def[i:]])
|
||||||
sql = "CAST(DATE_FORMAT(%s, '%s') AS DATETIME)" % (field_name, format_str)
|
sql = "CAST(DATE_FORMAT(%s, '%s') AS DATETIME)" % (field_name, format_str)
|
||||||
return sql
|
return sql, params
|
||||||
|
|
||||||
def date_interval_sql(self, sql, connector, timedelta):
|
def date_interval_sql(self, sql, connector, timedelta):
|
||||||
return "(%s %s INTERVAL '%d 0:0:%d:%d' DAY_MICROSECOND)" % (sql, connector,
|
return "(%s %s INTERVAL '%d 0:0:%d:%d' DAY_MICROSECOND)" % (sql, connector,
|
||||||
|
|
|
@ -7,6 +7,7 @@ from __future__ import unicode_literals
|
||||||
|
|
||||||
import datetime
|
import datetime
|
||||||
import decimal
|
import decimal
|
||||||
|
import re
|
||||||
import sys
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
|
@ -131,8 +132,9 @@ WHEN (new.%(col_name)s IS NULL)
|
||||||
if lookup_type == 'week_day':
|
if lookup_type == 'week_day':
|
||||||
# TO_CHAR(field, 'D') returns an integer from 1-7, where 1=Sunday.
|
# TO_CHAR(field, 'D') returns an integer from 1-7, where 1=Sunday.
|
||||||
return "TO_CHAR(%s, 'D')" % field_name
|
return "TO_CHAR(%s, 'D')" % field_name
|
||||||
# http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions050.htm
|
else:
|
||||||
return "EXTRACT(%s FROM %s)" % (lookup_type.upper(), field_name)
|
# http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions050.htm
|
||||||
|
return "EXTRACT(%s FROM %s)" % (lookup_type.upper(), field_name)
|
||||||
|
|
||||||
def date_interval_sql(self, sql, connector, timedelta):
|
def date_interval_sql(self, sql, connector, timedelta):
|
||||||
"""
|
"""
|
||||||
|
@ -155,29 +157,52 @@ WHEN (new.%(col_name)s IS NULL)
|
||||||
else:
|
else:
|
||||||
return "TRUNC(%s)" % field_name
|
return "TRUNC(%s)" % field_name
|
||||||
|
|
||||||
def datetime_extract_sql(self, lookup_type, field_name):
|
# Oracle crashes with "ORA-03113: end-of-file on communication channel"
|
||||||
|
# if the time zone name is passed in parameter. Use interpolation instead.
|
||||||
|
# https://groups.google.com/forum/#!msg/django-developers/zwQju7hbG78/9l934yelwfsJ
|
||||||
|
# This regexp matches all time zone names from the zoneinfo database.
|
||||||
|
_tzname_re = re.compile(r'^[\w/+-]+$')
|
||||||
|
|
||||||
|
def _convert_field_to_tz(self, field_name, tzname):
|
||||||
|
if not self._tzname_re.match(tzname):
|
||||||
|
raise ValueError("Invalid time zone name: %s" % tzname)
|
||||||
|
# Convert from UTC to local time, returning TIMESTAMP WITH TIME ZONE.
|
||||||
|
result = "(FROM_TZ(%s, 'UTC') AT TIME ZONE '%s')" % (field_name, tzname)
|
||||||
|
# Extracting from a TIMESTAMP WITH TIME ZONE ignore the time zone.
|
||||||
|
# Convert to a DATETIME, which is called DATE by Oracle. There's no
|
||||||
|
# built-in function to do that; the easiest is to go through a string.
|
||||||
|
result = "TO_CHAR(%s, 'YYYY-MM-DD HH24:MI:SS')" % result
|
||||||
|
result = "TO_DATE(%s, 'YYYY-MM-DD HH24:MI:SS')" % result
|
||||||
|
# Re-convert to a TIMESTAMP because EXTRACT only handles the date part
|
||||||
|
# on DATE values, even though they actually store the time part.
|
||||||
|
return "CAST(%s AS TIMESTAMP)" % result
|
||||||
|
|
||||||
|
def datetime_extract_sql(self, lookup_type, field_name, tzname):
|
||||||
if settings.USE_TZ:
|
if settings.USE_TZ:
|
||||||
field_name = "CAST((FROM_TZ(%s, 'UTC') AT TIME ZONE (%%s)) AS DATE)" % field_name
|
field_name = self._convert_field_to_tz(field_name, tzname)
|
||||||
if lookup_type == 'week_day':
|
if lookup_type == 'week_day':
|
||||||
# TO_CHAR(field, 'D') returns an integer from 1-7, where 1=Sunday.
|
# TO_CHAR(field, 'D') returns an integer from 1-7, where 1=Sunday.
|
||||||
return "TO_CHAR(%s, 'D')" % field_name
|
sql = "TO_CHAR(%s, 'D')" % field_name
|
||||||
# http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions050.htm
|
else:
|
||||||
return "EXTRACT(%s FROM %s)" % (lookup_type.upper(), field_name)
|
# http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions050.htm
|
||||||
|
sql = "EXTRACT(%s FROM %s)" % (lookup_type.upper(), field_name)
|
||||||
|
return sql, []
|
||||||
|
|
||||||
def datetime_trunc_sql(self, lookup_type, field_name):
|
def datetime_trunc_sql(self, lookup_type, field_name, tzname):
|
||||||
if settings.USE_TZ:
|
if settings.USE_TZ:
|
||||||
field_name = "CAST((FROM_TZ(%s, 'UTC') AT TIME ZONE (%%s)) AS DATE)" % field_name
|
field_name = self._convert_field_to_tz(field_name, tzname)
|
||||||
# http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions230.htm#i1002084
|
# http://docs.oracle.com/cd/B19306_01/server.102/b14200/functions230.htm#i1002084
|
||||||
if lookup_type in ('year', 'month'):
|
if lookup_type in ('year', 'month'):
|
||||||
return "TRUNC(%s, '%s')" % (field_name, lookup_type.upper())
|
sql = "TRUNC(%s, '%s')" % (field_name, lookup_type.upper())
|
||||||
elif lookup_type == 'day':
|
elif lookup_type == 'day':
|
||||||
return "TRUNC(%s)" % field_name
|
sql = "TRUNC(%s)" % field_name
|
||||||
elif lookup_type == 'hour':
|
elif lookup_type == 'hour':
|
||||||
return "TRUNC(%s, 'HH24')" % field_name
|
sql = "TRUNC(%s, 'HH24')" % field_name
|
||||||
elif lookup_type == 'minute':
|
elif lookup_type == 'minute':
|
||||||
return "TRUNC(%s, 'MI')" % field_name
|
sql = "TRUNC(%s, 'MI')" % field_name
|
||||||
else:
|
else:
|
||||||
return field_name
|
sql = field_name # Cast to DATE removes sub-second precision.
|
||||||
|
return sql, []
|
||||||
|
|
||||||
def convert_values(self, value, field):
|
def convert_values(self, value, field):
|
||||||
if isinstance(value, Database.LOB):
|
if isinstance(value, Database.LOB):
|
||||||
|
|
|
@ -37,21 +37,29 @@ class DatabaseOperations(BaseDatabaseOperations):
|
||||||
# http://www.postgresql.org/docs/8.0/static/functions-datetime.html#FUNCTIONS-DATETIME-TRUNC
|
# http://www.postgresql.org/docs/8.0/static/functions-datetime.html#FUNCTIONS-DATETIME-TRUNC
|
||||||
return "DATE_TRUNC('%s', %s)" % (lookup_type, field_name)
|
return "DATE_TRUNC('%s', %s)" % (lookup_type, field_name)
|
||||||
|
|
||||||
def datetime_extract_sql(self, lookup_type, field_name):
|
def datetime_extract_sql(self, lookup_type, field_name, tzname):
|
||||||
if settings.USE_TZ:
|
if settings.USE_TZ:
|
||||||
field_name = "%s AT TIME ZONE %%s" % field_name
|
field_name = "%s AT TIME ZONE %%s" % field_name
|
||||||
|
params = [tzname]
|
||||||
|
else:
|
||||||
|
params = []
|
||||||
# http://www.postgresql.org/docs/8.0/static/functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT
|
# http://www.postgresql.org/docs/8.0/static/functions-datetime.html#FUNCTIONS-DATETIME-EXTRACT
|
||||||
if lookup_type == 'week_day':
|
if lookup_type == 'week_day':
|
||||||
# For consistency across backends, we return Sunday=1, Saturday=7.
|
# For consistency across backends, we return Sunday=1, Saturday=7.
|
||||||
return "EXTRACT('dow' FROM %s) + 1" % field_name
|
sql = "EXTRACT('dow' FROM %s) + 1" % field_name
|
||||||
else:
|
else:
|
||||||
return "EXTRACT('%s' FROM %s)" % (lookup_type, field_name)
|
sql = "EXTRACT('%s' FROM %s)" % (lookup_type, field_name)
|
||||||
|
return sql, params
|
||||||
|
|
||||||
def datetime_trunc_sql(self, lookup_type, field_name):
|
def datetime_trunc_sql(self, lookup_type, field_name, tzname):
|
||||||
if settings.USE_TZ:
|
if settings.USE_TZ:
|
||||||
field_name = "%s AT TIME ZONE %%s" % field_name
|
field_name = "%s AT TIME ZONE %%s" % field_name
|
||||||
|
params = [tzname]
|
||||||
|
else:
|
||||||
|
params = []
|
||||||
# http://www.postgresql.org/docs/8.0/static/functions-datetime.html#FUNCTIONS-DATETIME-TRUNC
|
# http://www.postgresql.org/docs/8.0/static/functions-datetime.html#FUNCTIONS-DATETIME-TRUNC
|
||||||
return "DATE_TRUNC('%s', %s)" % (lookup_type, field_name)
|
sql = "DATE_TRUNC('%s', %s)" % (lookup_type, field_name)
|
||||||
|
return sql, params
|
||||||
|
|
||||||
def deferrable_sql(self):
|
def deferrable_sql(self):
|
||||||
return " DEFERRABLE INITIALLY DEFERRED"
|
return " DEFERRABLE INITIALLY DEFERRED"
|
||||||
|
|
|
@ -172,31 +172,25 @@ class DatabaseOperations(BaseDatabaseOperations):
|
||||||
# cause a collision with a field name).
|
# cause a collision with a field name).
|
||||||
return "django_date_trunc('%s', %s)" % (lookup_type.lower(), field_name)
|
return "django_date_trunc('%s', %s)" % (lookup_type.lower(), field_name)
|
||||||
|
|
||||||
def datetime_extract_sql(self, lookup_type, field_name):
|
def datetime_extract_sql(self, lookup_type, field_name, tzname):
|
||||||
# Same comment as in date_extract_sql.
|
# Same comment as in date_extract_sql.
|
||||||
if settings.USE_TZ:
|
if settings.USE_TZ:
|
||||||
if pytz is None:
|
if pytz is None:
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
raise ImproperlyConfigured("This query requires pytz, "
|
raise ImproperlyConfigured("This query requires pytz, "
|
||||||
"but it isn't installed.")
|
"but it isn't installed.")
|
||||||
return "django_datetime_extract('%s', %s, %%s)" % (
|
return "django_datetime_extract('%s', %s, %%s)" % (
|
||||||
lookup_type.lower(), field_name)
|
lookup_type.lower(), field_name), [tzname]
|
||||||
else:
|
|
||||||
return "django_datetime_extract('%s', %s, NULL)" % (
|
|
||||||
lookup_type.lower(), field_name)
|
|
||||||
|
|
||||||
def datetime_trunc_sql(self, lookup_type, field_name):
|
def datetime_trunc_sql(self, lookup_type, field_name, tzname):
|
||||||
# Same comment as in date_trunc_sql.
|
# Same comment as in date_trunc_sql.
|
||||||
if settings.USE_TZ:
|
if settings.USE_TZ:
|
||||||
if pytz is None:
|
if pytz is None:
|
||||||
from django.core.exceptions import ImproperlyConfigured
|
from django.core.exceptions import ImproperlyConfigured
|
||||||
raise ImproperlyConfigured("This query requires pytz, "
|
raise ImproperlyConfigured("This query requires pytz, "
|
||||||
"but it isn't installed.")
|
"but it isn't installed.")
|
||||||
return "django_datetime_trunc('%s', %s, %%s)" % (
|
return "django_datetime_trunc('%s', %s, %%s)" % (
|
||||||
lookup_type.lower(), field_name)
|
lookup_type.lower(), field_name), [tzname]
|
||||||
else:
|
|
||||||
return "django_datetime_trunc('%s', %s, NULL)" % (
|
|
||||||
lookup_type.lower(), field_name)
|
|
||||||
|
|
||||||
def drop_foreignkey_sql(self):
|
def drop_foreignkey_sql(self):
|
||||||
return ""
|
return ""
|
||||||
|
|
|
@ -1034,13 +1034,6 @@ class SQLDateCompiler(SQLCompiler):
|
||||||
yield date
|
yield date
|
||||||
|
|
||||||
class SQLDateTimeCompiler(SQLCompiler):
|
class SQLDateTimeCompiler(SQLCompiler):
|
||||||
def as_sql(self):
|
|
||||||
sql, params = super(SQLDateTimeCompiler, self).as_sql()
|
|
||||||
if settings.USE_TZ:
|
|
||||||
tzname = timezone._get_timezone_name(self.query.tzinfo)
|
|
||||||
params = (tzname,) + params
|
|
||||||
return sql, params
|
|
||||||
|
|
||||||
def results_iter(self):
|
def results_iter(self):
|
||||||
"""
|
"""
|
||||||
Returns an iterator over the results from executing this query.
|
Returns an iterator over the results from executing this query.
|
||||||
|
|
|
@ -26,8 +26,6 @@ class Date(object):
|
||||||
"""
|
"""
|
||||||
Add a date selection column.
|
Add a date selection column.
|
||||||
"""
|
"""
|
||||||
trunc_func = 'date_trunc_sql'
|
|
||||||
|
|
||||||
def __init__(self, col, lookup_type):
|
def __init__(self, col, lookup_type):
|
||||||
self.col = col
|
self.col = col
|
||||||
self.lookup_type = lookup_type
|
self.lookup_type = lookup_type
|
||||||
|
@ -42,10 +40,25 @@ class Date(object):
|
||||||
col = '%s.%s' % tuple([qn(c) for c in self.col])
|
col = '%s.%s' % tuple([qn(c) for c in self.col])
|
||||||
else:
|
else:
|
||||||
col = self.col
|
col = self.col
|
||||||
return getattr(connection.ops, self.trunc_func)(self.lookup_type, col), []
|
return connection.ops.date_trunc_sql(self.lookup_type, col), []
|
||||||
|
|
||||||
class DateTime(Date):
|
class DateTime(object):
|
||||||
"""
|
"""
|
||||||
Add a datetime selection column.
|
Add a datetime selection column.
|
||||||
"""
|
"""
|
||||||
trunc_func = 'datetime_trunc_sql'
|
def __init__(self, col, lookup_type, tzname):
|
||||||
|
self.col = col
|
||||||
|
self.lookup_type = lookup_type
|
||||||
|
self.tzname = tzname
|
||||||
|
|
||||||
|
def relabel_aliases(self, change_map):
|
||||||
|
c = self.col
|
||||||
|
if isinstance(c, (list, tuple)):
|
||||||
|
self.col = (change_map.get(c[0], c[0]), c[1])
|
||||||
|
|
||||||
|
def as_sql(self, qn, connection):
|
||||||
|
if isinstance(self.col, (list, tuple)):
|
||||||
|
col = '%s.%s' % tuple([qn(c) for c in self.col])
|
||||||
|
else:
|
||||||
|
col = self.col
|
||||||
|
return connection.ops.datetime_trunc_sql(self.lookup_type, col, self.tzname)
|
||||||
|
|
|
@ -14,6 +14,7 @@ from django.db.models.sql.where import AND, Constraint
|
||||||
from django.utils.functional import Promise
|
from django.utils.functional import Promise
|
||||||
from django.utils.encoding import force_text
|
from django.utils.encoding import force_text
|
||||||
from django.utils import six
|
from django.utils import six
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
|
|
||||||
__all__ = ['DeleteQuery', 'UpdateQuery', 'InsertQuery', 'DateQuery',
|
__all__ = ['DeleteQuery', 'UpdateQuery', 'InsertQuery', 'DateQuery',
|
||||||
|
@ -222,7 +223,6 @@ class DateQuery(Query):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
compiler = 'SQLDateCompiler'
|
compiler = 'SQLDateCompiler'
|
||||||
select_type = Date
|
|
||||||
|
|
||||||
def add_select(self, field_name, lookup_type, order='ASC'):
|
def add_select(self, field_name, lookup_type, order='ASC'):
|
||||||
"""
|
"""
|
||||||
|
@ -241,7 +241,7 @@ class DateQuery(Query):
|
||||||
field = result[0]
|
field = result[0]
|
||||||
self._check_field(field) # overridden in DateTimeQuery
|
self._check_field(field) # overridden in DateTimeQuery
|
||||||
alias = result[3][-1]
|
alias = result[3][-1]
|
||||||
select = self.select_type((alias, field.column), lookup_type)
|
select = self._get_select((alias, field.column), lookup_type)
|
||||||
self.clear_select_clause()
|
self.clear_select_clause()
|
||||||
self.select = [SelectInfo(select, None)]
|
self.select = [SelectInfo(select, None)]
|
||||||
self.distinct = True
|
self.distinct = True
|
||||||
|
@ -257,6 +257,9 @@ class DateQuery(Query):
|
||||||
assert not isinstance(field, DateTimeField), \
|
assert not isinstance(field, DateTimeField), \
|
||||||
"%r is a DateTimeField, not a DateField." % field.name
|
"%r is a DateTimeField, not a DateField." % field.name
|
||||||
|
|
||||||
|
def _get_select(self, col, lookup_type):
|
||||||
|
return Date(col, lookup_type)
|
||||||
|
|
||||||
class DateTimeQuery(DateQuery):
|
class DateTimeQuery(DateQuery):
|
||||||
"""
|
"""
|
||||||
A DateTimeQuery is like a DateQuery but for a datetime field. If time zone
|
A DateTimeQuery is like a DateQuery but for a datetime field. If time zone
|
||||||
|
@ -265,12 +268,18 @@ class DateTimeQuery(DateQuery):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
compiler = 'SQLDateTimeCompiler'
|
compiler = 'SQLDateTimeCompiler'
|
||||||
select_type = DateTime
|
|
||||||
|
|
||||||
def _check_field(self, field):
|
def _check_field(self, field):
|
||||||
assert isinstance(field, DateTimeField), \
|
assert isinstance(field, DateTimeField), \
|
||||||
"%r isn't a DateTimeField." % field.name
|
"%r isn't a DateTimeField." % field.name
|
||||||
|
|
||||||
|
def _get_select(self, col, lookup_type):
|
||||||
|
if self.tzinfo is None:
|
||||||
|
tzname = None
|
||||||
|
else:
|
||||||
|
tzname = timezone._get_timezone_name(self.tzinfo)
|
||||||
|
return DateTime(col, lookup_type, tzname)
|
||||||
|
|
||||||
class AggregateQuery(Query):
|
class AggregateQuery(Query):
|
||||||
"""
|
"""
|
||||||
An AggregateQuery takes another query as a parameter to the FROM
|
An AggregateQuery takes another query as a parameter to the FROM
|
||||||
|
|
|
@ -226,10 +226,9 @@ class WhereNode(tree.Node):
|
||||||
return ('%s BETWEEN %%s and %%s' % field_sql, params)
|
return ('%s BETWEEN %%s and %%s' % field_sql, params)
|
||||||
elif is_datetime_field and lookup_type in ('month', 'day', 'week_day',
|
elif is_datetime_field and lookup_type in ('month', 'day', 'week_day',
|
||||||
'hour', 'minute', 'second'):
|
'hour', 'minute', 'second'):
|
||||||
if settings.USE_TZ:
|
tzname = timezone.get_current_timezone_name() if settings.USE_TZ else None
|
||||||
params = [timezone.get_current_timezone_name()] + params
|
sql, tz_params = connection.ops.datetime_extract_sql(lookup_type, field_sql, tzname)
|
||||||
return ('%s = %%s'
|
return ('%s = %%s' % sql, tz_params + params)
|
||||||
% connection.ops.datetime_extract_sql(lookup_type, field_sql), params)
|
|
||||||
elif lookup_type in ('month', 'day', 'week_day'):
|
elif lookup_type in ('month', 'day', 'week_day'):
|
||||||
return ('%s = %%s'
|
return ('%s = %%s'
|
||||||
% connection.ops.date_extract_sql(lookup_type, field_sql), params)
|
% connection.ops.date_extract_sql(lookup_type, field_sql), params)
|
||||||
|
|
Loading…
Reference in New Issue