Loading django/db/backends/base/operations.py +7 −0 Original line number Diff line number Diff line Loading @@ -122,6 +122,13 @@ class BaseDatabaseOperations(object): """ raise NotImplementedError('subclasses of BaseDatabaseOperations may require a datetime_trunk_sql() method') def time_extract_sql(self, lookup_type, field_name): """ Given a lookup_type of 'hour', 'minute' or 'second', returns the SQL that extracts a value from the given time field field_name. """ return self.date_extract_sql(lookup_type, field_name) def deferrable_sql(self): """ Returns the SQL necessary to make a constraint "initially deferred" Loading django/db/backends/sqlite3/base.py +11 −0 Original line number Diff line number Diff line Loading @@ -210,6 +210,7 @@ class DatabaseWrapper(BaseDatabaseWrapper): conn.create_function("django_datetime_cast_date", 2, _sqlite_datetime_cast_date) conn.create_function("django_datetime_extract", 3, _sqlite_datetime_extract) conn.create_function("django_datetime_trunc", 3, _sqlite_datetime_trunc) conn.create_function("django_time_extract", 2, _sqlite_time_extract) conn.create_function("regexp", 2, _sqlite_regexp) conn.create_function("django_format_dtdelta", 3, _sqlite_format_dtdelta) conn.create_function("django_power", 2, _sqlite_power) Loading Loading @@ -402,6 +403,16 @@ def _sqlite_datetime_trunc(lookup_type, dt, tzname): return "%i-%02i-%02i %02i:%02i:%02i" % (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second) def _sqlite_time_extract(lookup_type, dt): if dt is None: return None try: dt = backend_utils.typecast_time(dt) except (ValueError, TypeError): return None return getattr(dt, lookup_type) def _sqlite_format_dtdelta(conn, lhs, rhs): """ LHS and RHS can be either: Loading django/db/backends/sqlite3/operations.py +7 −0 Original line number Diff line number Diff line Loading @@ -88,6 +88,13 @@ class DatabaseOperations(BaseDatabaseOperations): return "django_datetime_trunc('%s', %s, %%s)" % ( lookup_type.lower(), field_name), [tzname] def time_extract_sql(self, lookup_type, field_name): # sqlite doesn't support extract, so we fake it with the user-defined # function django_time_extract that's registered in connect(). Note that # single quotes are used because this is a string (and could otherwise # cause a collision with a field name). return "django_time_extract('%s', %s)" % (lookup_type.lower(), field_name) def drop_foreignkey_sql(self): return "" Loading django/db/models/fields/__init__.py +5 −2 Original line number Diff line number Diff line Loading @@ -2416,9 +2416,12 @@ class DateTransform(Transform): tzname = timezone.get_current_timezone_name() if settings.USE_TZ else None sql, tz_params = connection.ops.datetime_extract_sql(self.lookup_name, sql, tzname) params.extend(tz_params) else: # DateField and TimeField. elif isinstance(lhs_output_field, DateField): sql = connection.ops.date_extract_sql(self.lookup_name, sql) elif isinstance(lhs_output_field, TimeField): sql = connection.ops.time_extract_sql(self.lookup_name, sql) else: raise ValueError('DateTransform only valid on Date/Time/DateTimeFields') return sql, params @cached_property Loading docs/ref/models/querysets.txt +33 −12 Original line number Diff line number Diff line Loading @@ -2606,23 +2606,30 @@ in the database <database-time-zone-definitions>`. hour ~~~~ For datetime fields, an exact hour match. Allows chaining additional field lookups. Takes an integer between 0 and 23. For datetime and time fields, an exact hour match. Allows chaining additional field lookups. Takes an integer between 0 and 23. Example:: Event.objects.filter(timestamp__hour=23) Event.objects.filter(time__hour=5) Event.objects.filter(timestamp__hour__gte=12) SQL equivalent:: SELECT ... WHERE EXTRACT('hour' FROM timestamp) = '23'; SELECT ... WHERE EXTRACT('hour' FROM time) = '5'; SELECT ... WHERE EXTRACT('hour' FROM timestamp) >= '12'; (The exact SQL syntax varies for each database engine.) When :setting:`USE_TZ` is ``True``, values are converted to the current time zone before filtering. For datetime fields, when :setting:`USE_TZ` is ``True``, values are converted to the current time zone before filtering. .. versionchanged:: 1.9 Added support for :class:`~django.db.models.TimeField` on SQLite (other databases supported it as of 1.7). .. versionchanged:: 1.9 Loading @@ -2633,23 +2640,30 @@ zone before filtering. minute ~~~~~~ For datetime fields, an exact minute match. Allows chaining additional field lookups. Takes an integer between 0 and 59. For datetime and time fields, an exact minute match. Allows chaining additional field lookups. Takes an integer between 0 and 59. Example:: Event.objects.filter(timestamp__minute=29) Event.objects.filter(time__minute=46) Event.objects.filter(timestamp__minute__gte=29) SQL equivalent:: SELECT ... WHERE EXTRACT('minute' FROM timestamp) = '29'; SELECT ... WHERE EXTRACT('minute' FROM time) = '46'; SELECT ... WHERE EXTRACT('minute' FROM timestamp) >= '29'; (The exact SQL syntax varies for each database engine.) When :setting:`USE_TZ` is ``True``, values are converted to the current time zone before filtering. For datetime fields, When :setting:`USE_TZ` is ``True``, values are converted to the current time zone before filtering. .. versionchanged:: 1.9 Added support for :class:`~django.db.models.TimeField` on SQLite (other databases supported it as of 1.7). .. versionchanged:: 1.9 Loading @@ -2660,23 +2674,30 @@ zone before filtering. second ~~~~~~ For datetime fields, an exact second match. Allows chaining additional field lookups. Takes an integer between 0 and 59. For datetime and time fields, an exact second match. Allows chaining additional field lookups. Takes an integer between 0 and 59. Example:: Event.objects.filter(timestamp__second=31) Event.objects.filter(time__second=2) Event.objects.filter(timestamp__second__gte=31) SQL equivalent:: SELECT ... WHERE EXTRACT('second' FROM timestamp) = '31'; SELECT ... WHERE EXTRACT('second' FROM time) = '2'; SELECT ... WHERE EXTRACT('second' FROM timestamp) >= '31'; (The exact SQL syntax varies for each database engine.) When :setting:`USE_TZ` is ``True``, values are converted to the current time zone before filtering. For datetime fields, when :setting:`USE_TZ` is ``True``, values are converted to the current time zone before filtering. .. versionchanged:: 1.9 Added support for :class:`~django.db.models.TimeField` on SQLite (other databases supported it as of 1.7). .. versionchanged:: 1.9 Loading Loading
django/db/backends/base/operations.py +7 −0 Original line number Diff line number Diff line Loading @@ -122,6 +122,13 @@ class BaseDatabaseOperations(object): """ raise NotImplementedError('subclasses of BaseDatabaseOperations may require a datetime_trunk_sql() method') def time_extract_sql(self, lookup_type, field_name): """ Given a lookup_type of 'hour', 'minute' or 'second', returns the SQL that extracts a value from the given time field field_name. """ return self.date_extract_sql(lookup_type, field_name) def deferrable_sql(self): """ Returns the SQL necessary to make a constraint "initially deferred" Loading
django/db/backends/sqlite3/base.py +11 −0 Original line number Diff line number Diff line Loading @@ -210,6 +210,7 @@ class DatabaseWrapper(BaseDatabaseWrapper): conn.create_function("django_datetime_cast_date", 2, _sqlite_datetime_cast_date) conn.create_function("django_datetime_extract", 3, _sqlite_datetime_extract) conn.create_function("django_datetime_trunc", 3, _sqlite_datetime_trunc) conn.create_function("django_time_extract", 2, _sqlite_time_extract) conn.create_function("regexp", 2, _sqlite_regexp) conn.create_function("django_format_dtdelta", 3, _sqlite_format_dtdelta) conn.create_function("django_power", 2, _sqlite_power) Loading Loading @@ -402,6 +403,16 @@ def _sqlite_datetime_trunc(lookup_type, dt, tzname): return "%i-%02i-%02i %02i:%02i:%02i" % (dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second) def _sqlite_time_extract(lookup_type, dt): if dt is None: return None try: dt = backend_utils.typecast_time(dt) except (ValueError, TypeError): return None return getattr(dt, lookup_type) def _sqlite_format_dtdelta(conn, lhs, rhs): """ LHS and RHS can be either: Loading
django/db/backends/sqlite3/operations.py +7 −0 Original line number Diff line number Diff line Loading @@ -88,6 +88,13 @@ class DatabaseOperations(BaseDatabaseOperations): return "django_datetime_trunc('%s', %s, %%s)" % ( lookup_type.lower(), field_name), [tzname] def time_extract_sql(self, lookup_type, field_name): # sqlite doesn't support extract, so we fake it with the user-defined # function django_time_extract that's registered in connect(). Note that # single quotes are used because this is a string (and could otherwise # cause a collision with a field name). return "django_time_extract('%s', %s)" % (lookup_type.lower(), field_name) def drop_foreignkey_sql(self): return "" Loading
django/db/models/fields/__init__.py +5 −2 Original line number Diff line number Diff line Loading @@ -2416,9 +2416,12 @@ class DateTransform(Transform): tzname = timezone.get_current_timezone_name() if settings.USE_TZ else None sql, tz_params = connection.ops.datetime_extract_sql(self.lookup_name, sql, tzname) params.extend(tz_params) else: # DateField and TimeField. elif isinstance(lhs_output_field, DateField): sql = connection.ops.date_extract_sql(self.lookup_name, sql) elif isinstance(lhs_output_field, TimeField): sql = connection.ops.time_extract_sql(self.lookup_name, sql) else: raise ValueError('DateTransform only valid on Date/Time/DateTimeFields') return sql, params @cached_property Loading
docs/ref/models/querysets.txt +33 −12 Original line number Diff line number Diff line Loading @@ -2606,23 +2606,30 @@ in the database <database-time-zone-definitions>`. hour ~~~~ For datetime fields, an exact hour match. Allows chaining additional field lookups. Takes an integer between 0 and 23. For datetime and time fields, an exact hour match. Allows chaining additional field lookups. Takes an integer between 0 and 23. Example:: Event.objects.filter(timestamp__hour=23) Event.objects.filter(time__hour=5) Event.objects.filter(timestamp__hour__gte=12) SQL equivalent:: SELECT ... WHERE EXTRACT('hour' FROM timestamp) = '23'; SELECT ... WHERE EXTRACT('hour' FROM time) = '5'; SELECT ... WHERE EXTRACT('hour' FROM timestamp) >= '12'; (The exact SQL syntax varies for each database engine.) When :setting:`USE_TZ` is ``True``, values are converted to the current time zone before filtering. For datetime fields, when :setting:`USE_TZ` is ``True``, values are converted to the current time zone before filtering. .. versionchanged:: 1.9 Added support for :class:`~django.db.models.TimeField` on SQLite (other databases supported it as of 1.7). .. versionchanged:: 1.9 Loading @@ -2633,23 +2640,30 @@ zone before filtering. minute ~~~~~~ For datetime fields, an exact minute match. Allows chaining additional field lookups. Takes an integer between 0 and 59. For datetime and time fields, an exact minute match. Allows chaining additional field lookups. Takes an integer between 0 and 59. Example:: Event.objects.filter(timestamp__minute=29) Event.objects.filter(time__minute=46) Event.objects.filter(timestamp__minute__gte=29) SQL equivalent:: SELECT ... WHERE EXTRACT('minute' FROM timestamp) = '29'; SELECT ... WHERE EXTRACT('minute' FROM time) = '46'; SELECT ... WHERE EXTRACT('minute' FROM timestamp) >= '29'; (The exact SQL syntax varies for each database engine.) When :setting:`USE_TZ` is ``True``, values are converted to the current time zone before filtering. For datetime fields, When :setting:`USE_TZ` is ``True``, values are converted to the current time zone before filtering. .. versionchanged:: 1.9 Added support for :class:`~django.db.models.TimeField` on SQLite (other databases supported it as of 1.7). .. versionchanged:: 1.9 Loading @@ -2660,23 +2674,30 @@ zone before filtering. second ~~~~~~ For datetime fields, an exact second match. Allows chaining additional field lookups. Takes an integer between 0 and 59. For datetime and time fields, an exact second match. Allows chaining additional field lookups. Takes an integer between 0 and 59. Example:: Event.objects.filter(timestamp__second=31) Event.objects.filter(time__second=2) Event.objects.filter(timestamp__second__gte=31) SQL equivalent:: SELECT ... WHERE EXTRACT('second' FROM timestamp) = '31'; SELECT ... WHERE EXTRACT('second' FROM time) = '2'; SELECT ... WHERE EXTRACT('second' FROM timestamp) >= '31'; (The exact SQL syntax varies for each database engine.) When :setting:`USE_TZ` is ``True``, values are converted to the current time zone before filtering. For datetime fields, when :setting:`USE_TZ` is ``True``, values are converted to the current time zone before filtering. .. versionchanged:: 1.9 Added support for :class:`~django.db.models.TimeField` on SQLite (other databases supported it as of 1.7). .. versionchanged:: 1.9 Loading