diff --git a/django/db/backends/sqlite3/base.py b/django/db/backends/sqlite3/base.py
index bc97f5c..3239adf 100644
a
|
b
|
def _sqlite_date_trunc(lookup_type, dt):
|
238 | 238 | return "%i-%02i-01 00:00:00" % (dt.year, dt.month) |
239 | 239 | elif lookup_type == 'day': |
240 | 240 | return "%i-%02i-%02i 00:00:00" % (dt.year, dt.month, dt.day) |
241 | | |
| 241 | elif lookup_type == 'hour': |
| 242 | return "%i-%02i-%02i %02i:00:00" % (dt.year, dt.month, dt.day, dt.hour) |
| 243 | elif lookup_type == 'minute': |
| 244 | return "%i-%02i-%02i %02i:%02i:00" % (dt.year, dt.month, dt.day, dt.hour, dt.minute) |
| 245 | |
242 | 246 | def _sqlite_regexp(re_pattern, re_string): |
243 | 247 | import re |
244 | 248 | try: |
diff --git a/django/db/models/query.py b/django/db/models/query.py
index d9fbd9b..10ed740 100644
a
|
b
|
class QuerySet(object):
|
518 | 518 | Returns a list of datetime objects representing all available dates for |
519 | 519 | the given field_name, scoped to 'kind'. |
520 | 520 | """ |
521 | | assert kind in ("month", "year", "day"), \ |
522 | | "'kind' must be one of 'year', 'month' or 'day'." |
| 521 | assert kind in ("month", "year", "day", "hour", "minute"), \ |
| 522 | "'kind' must be one of 'year', 'month', 'day', 'hour' or 'minute'." |
523 | 523 | assert order in ('ASC', 'DESC'), \ |
524 | 524 | "'order' must be either 'ASC' or 'DESC'." |
525 | 525 | return self._clone(klass=DateQuerySet, setup=True, |
diff --git a/docs/ref/models/querysets.txt b/docs/ref/models/querysets.txt
index 56ff644..4578bd4 100644
a
|
b
|
kind within the contents of the ``QuerySet``.
|
502 | 502 | ``field`` should be the name of a ``DateField`` or ``DateTimeField`` of your |
503 | 503 | model. |
504 | 504 | |
505 | | ``kind`` should be either ``"year"``, ``"month"`` or ``"day"``. Each |
506 | | ``datetime.datetime`` object in the result list is "truncated" to the given |
507 | | ``type``. |
| 505 | ``kind`` should be either ``"year"``, ``"month"``, ``"day"``, ``"hour"`` or |
| 506 | ``"minute"``. Each ``datetime.datetime`` object in the result list is |
| 507 | "truncated" to the given ``type``. |
508 | 508 | |
509 | 509 | * ``"year"`` returns a list of all distinct year values for the field. |
510 | 510 | * ``"month"`` returns a list of all distinct year/month values for the field. |
511 | 511 | * ``"day"`` returns a list of all distinct year/month/day values for the field. |
| 512 | * ``"hour"`` returns a list of all distinct year/month/day/hour values for the field. |
| 513 | * ``"minute"`` returns a list of all distinct year/month/day/hour/minute values for the field. |
512 | 514 | |
513 | 515 | ``order``, which defaults to ``'ASC'``, should be either ``'ASC'`` or |
514 | 516 | ``'DESC'``. This specifies how to order the results. |
… |
… |
Examples::
|
523 | 525 | [datetime.datetime(2005, 2, 20), datetime.datetime(2005, 3, 20)] |
524 | 526 | >>> Entry.objects.dates('pub_date', 'day', order='DESC') |
525 | 527 | [datetime.datetime(2005, 3, 20), datetime.datetime(2005, 2, 20)] |
| 528 | >>> Entry.objects.dates('pub_date', 'hour', order='DESC') |
| 529 | [datetime.datetime(2005, 3, 20, 10), datetime.datetime(2005, 2, 20, 12)] |
| 530 | >>> Entry.objects.dates('pub_date', 'minute', order='DESC') |
| 531 | [datetime.datetime(2005, 3, 20, 10, 30), datetime.datetime(2005, 2, 20, 12, 45)] |
526 | 532 | >>> Entry.objects.filter(headline__contains='Lennon').dates('pub_date', 'day') |
527 | 533 | [datetime.datetime(2005, 3, 20)] |
528 | 534 | |
diff --git a/tests/modeltests/basic/fixtures/datequeryset_test.json b/tests/modeltests/basic/fixtures/datequeryset_test.json
new file mode 100644
index 0000000..5e3a9c9
-
|
+
|
|
| 1 | [ |
| 2 | { |
| 3 | "pk": "1", |
| 4 | "model": "basic.article", |
| 5 | "fields": { |
| 6 | "headline": "Do DateQuerySets dream of electric sheep?", |
| 7 | "pub_date": "2010-05-28 10:15:30" |
| 8 | } |
| 9 | } |
| 10 | ] |
| 11 | No newline at end of file |
diff --git a/tests/modeltests/basic/models.py b/tests/modeltests/basic/models.py
index ad2e965..f3c2a11 100644
a
|
b
|
FieldDoesNotExist: Article has no field named 'invalid_field'
|
234 | 234 | >>> Article.objects.dates('pub_date', 'bad_kind') |
235 | 235 | Traceback (most recent call last): |
236 | 236 | ... |
237 | | AssertionError: 'kind' must be one of 'year', 'month' or 'day'. |
| 237 | AssertionError: 'kind' must be one of 'year', 'month', 'day', 'hour' or 'minute'. |
238 | 238 | |
239 | 239 | >>> Article.objects.dates('pub_date', 'year', order='bad order') |
240 | 240 | Traceback (most recent call last): |
diff --git a/tests/modeltests/basic/tests.py b/tests/modeltests/basic/tests.py
new file mode 100644
index 0000000..3afc504
-
|
+
|
|
| 1 | from django.test import TestCase |
| 2 | from models import Article |
| 3 | |
| 4 | class DateQuerySetTest(TestCase): |
| 5 | fixtures = ['datequeryset_test.json'] |
| 6 | |
| 7 | def testDatesHoursMinutes(self): |
| 8 | res = Article.objects.dates('pub_date', 'hour') |
| 9 | self.assertEqual(repr(res), "[datetime.datetime(2010, 5, 28, 10, 0)]") |
| 10 | |
| 11 | res = Article.objects.dates('pub_date', 'minute') |
| 12 | self.assertEqual(repr(res), "[datetime.datetime(2010, 5, 28, 10, 15)]") |