Permalink
Browse files

Updated and added tests for QuerySet.datetimes.

  • Loading branch information...
1 parent a8451a5 commit 50fb7a52462fecf0127b38e7f3df322aeb287c43 @aaugustin aaugustin committed Feb 10, 2013
@@ -397,6 +397,9 @@ class BaseDatabaseFeatures(object):
# Can datetimes with timezones be used?
supports_timezones = True
+ # Does the database have a copy of the zoneinfo database?
+ has_zoneinfo_database = True
+
# When performing a GROUP BY, is an ORDER BY NULL required
# to remove any ordering?
requires_explicit_null_ordering_when_grouping = False
@@ -189,13 +189,16 @@ def test_query_filter(self):
self.assertEqual(Event.objects.filter(dt__gte=dt2).count(), 1)
self.assertEqual(Event.objects.filter(dt__gt=dt2).count(), 0)
- def test_query_date_related_filters(self):
+ def test_query_datetime_lookups(self):
Event.objects.create(dt=datetime.datetime(2011, 1, 1, 1, 30, 0))
Event.objects.create(dt=datetime.datetime(2011, 1, 1, 4, 30, 0))
self.assertEqual(Event.objects.filter(dt__year=2011).count(), 2)
self.assertEqual(Event.objects.filter(dt__month=1).count(), 2)
self.assertEqual(Event.objects.filter(dt__day=1).count(), 2)
self.assertEqual(Event.objects.filter(dt__week_day=7).count(), 2)
+ self.assertEqual(Event.objects.filter(dt__hour=1).count(), 1)
+ self.assertEqual(Event.objects.filter(dt__minute=30).count(), 2)
+ self.assertEqual(Event.objects.filter(dt__second=0).count(), 2)
def test_query_aggregation(self):
# Only min and max make sense for datetimes.
@@ -230,15 +233,30 @@ def test_query_annotation(self):
[afternoon_min_dt],
transform=lambda d: d.dt)
- def test_query_dates(self):
+ def test_query_datetimes(self):
Event.objects.create(dt=datetime.datetime(2011, 1, 1, 1, 30, 0))
Event.objects.create(dt=datetime.datetime(2011, 1, 1, 4, 30, 0))
- self.assertQuerysetEqual(Event.objects.dates('dt', 'year'),
- [datetime.datetime(2011, 1, 1)], transform=lambda d: d)
- self.assertQuerysetEqual(Event.objects.dates('dt', 'month'),
- [datetime.datetime(2011, 1, 1)], transform=lambda d: d)
- self.assertQuerysetEqual(Event.objects.dates('dt', 'day'),
- [datetime.datetime(2011, 1, 1)], transform=lambda d: d)
+ self.assertQuerysetEqual(Event.objects.datetimes('dt', 'year'),
+ [datetime.datetime(2011, 1, 1, 0, 0, 0)],
+ transform=lambda d: d)
+ self.assertQuerysetEqual(Event.objects.datetimes('dt', 'month'),
+ [datetime.datetime(2011, 1, 1, 0, 0, 0)],
+ transform=lambda d: d)
+ self.assertQuerysetEqual(Event.objects.datetimes('dt', 'day'),
+ [datetime.datetime(2011, 1, 1, 0, 0, 0)],
+ transform=lambda d: d)
+ self.assertQuerysetEqual(Event.objects.datetimes('dt', 'hour'),
+ [datetime.datetime(2011, 1, 1, 1, 0, 0),
+ datetime.datetime(2011, 1, 1, 4, 0, 0)],
+ transform=lambda d: d)
+ self.assertQuerysetEqual(Event.objects.datetimes('dt', 'minute'),
+ [datetime.datetime(2011, 1, 1, 1, 30, 0),
+ datetime.datetime(2011, 1, 1, 4, 30, 0)],
+ transform=lambda d: d)
+ self.assertQuerysetEqual(Event.objects.datetimes('dt', 'second'),
+ [datetime.datetime(2011, 1, 1, 1, 30, 0),
+ datetime.datetime(2011, 1, 1, 4, 30, 0)],
+ transform=lambda d: d)
def test_raw_sql(self):
# Regression test for #17755
@@ -398,17 +416,32 @@ def test_query_filter_with_naive_datetime(self):
msg = str(warning.message)
self.assertTrue(msg.startswith("DateTimeField received a naive datetime"))
- def test_query_date_related_filters(self):
- # These two dates fall in the same day in EAT, but in different days,
- # years and months in UTC, and aggregation is performed in UTC when
- # time zone support is enabled. This test could be changed if the
- # implementation is changed to perform the aggregation is local time.
+ @skipUnlessDBFeature('has_zoneinfo_database')
+ def test_query_datetime_lookups(self):
Event.objects.create(dt=datetime.datetime(2011, 1, 1, 1, 30, 0, tzinfo=EAT))
Event.objects.create(dt=datetime.datetime(2011, 1, 1, 4, 30, 0, tzinfo=EAT))
- self.assertEqual(Event.objects.filter(dt__year=2011).count(), 1)
- self.assertEqual(Event.objects.filter(dt__month=1).count(), 1)
- self.assertEqual(Event.objects.filter(dt__day=1).count(), 1)
- self.assertEqual(Event.objects.filter(dt__week_day=7).count(), 1)
+ self.assertEqual(Event.objects.filter(dt__year=2011).count(), 2)
+ self.assertEqual(Event.objects.filter(dt__month=1).count(), 2)
+ self.assertEqual(Event.objects.filter(dt__day=1).count(), 2)
+ self.assertEqual(Event.objects.filter(dt__week_day=7).count(), 2)
+ self.assertEqual(Event.objects.filter(dt__hour=1).count(), 1)
+ self.assertEqual(Event.objects.filter(dt__minute=30).count(), 2)
+ self.assertEqual(Event.objects.filter(dt__second=0).count(), 2)
+
+ @skipUnlessDBFeature('has_zoneinfo_database')
+ def test_query_datetime_lookups_in_other_timezone(self):
+ Event.objects.create(dt=datetime.datetime(2011, 1, 1, 1, 30, 0, tzinfo=EAT))
+ Event.objects.create(dt=datetime.datetime(2011, 1, 1, 4, 30, 0, tzinfo=EAT))
+ with timezone.override(UTC):
+ # These two dates fall in the same day in EAT, but in different days,
+ # years and months in UTC.
+ self.assertEqual(Event.objects.filter(dt__year=2011).count(), 1)
+ self.assertEqual(Event.objects.filter(dt__month=1).count(), 1)
+ self.assertEqual(Event.objects.filter(dt__day=1).count(), 1)
+ self.assertEqual(Event.objects.filter(dt__week_day=7).count(), 1)
+ self.assertEqual(Event.objects.filter(dt__hour=22).count(), 1)
+ self.assertEqual(Event.objects.filter(dt__minute=30).count(), 2)
+ self.assertEqual(Event.objects.filter(dt__second=0).count(), 2)
def test_query_aggregation(self):
# Only min and max make sense for datetimes.
@@ -443,22 +476,61 @@ def test_query_annotation(self):
[afternoon_min_dt],
transform=lambda d: d.dt)
- def test_query_dates(self):
- # Same comment as in test_query_date_related_filters.
+ @skipUnlessDBFeature('has_zoneinfo_database')
+ def test_query_datetimes(self):
Event.objects.create(dt=datetime.datetime(2011, 1, 1, 1, 30, 0, tzinfo=EAT))
Event.objects.create(dt=datetime.datetime(2011, 1, 1, 4, 30, 0, tzinfo=EAT))
- self.assertQuerysetEqual(Event.objects.dates('dt', 'year'),
- [datetime.datetime(2010, 1, 1, tzinfo=UTC),
- datetime.datetime(2011, 1, 1, tzinfo=UTC)],
+ self.assertQuerysetEqual(Event.objects.datetimes('dt', 'year'),
+ [datetime.datetime(2011, 1, 1, 0, 0, 0, tzinfo=EAT)],
+ transform=lambda d: d)
+ self.assertQuerysetEqual(Event.objects.datetimes('dt', 'month'),
+ [datetime.datetime(2011, 1, 1, 0, 0, 0, tzinfo=EAT)],
+ transform=lambda d: d)
+ self.assertQuerysetEqual(Event.objects.datetimes('dt', 'day'),
+ [datetime.datetime(2011, 1, 1, 0, 0, 0, tzinfo=EAT)],
transform=lambda d: d)
- self.assertQuerysetEqual(Event.objects.dates('dt', 'month'),
- [datetime.datetime(2010, 12, 1, tzinfo=UTC),
- datetime.datetime(2011, 1, 1, tzinfo=UTC)],
+ self.assertQuerysetEqual(Event.objects.datetimes('dt', 'hour'),
+ [datetime.datetime(2011, 1, 1, 1, 0, 0, tzinfo=EAT),
+ datetime.datetime(2011, 1, 1, 4, 0, 0, tzinfo=EAT)],
transform=lambda d: d)
- self.assertQuerysetEqual(Event.objects.dates('dt', 'day'),
- [datetime.datetime(2010, 12, 31, tzinfo=UTC),
- datetime.datetime(2011, 1, 1, tzinfo=UTC)],
+ self.assertQuerysetEqual(Event.objects.datetimes('dt', 'minute'),
+ [datetime.datetime(2011, 1, 1, 1, 30, 0, tzinfo=EAT),
+ datetime.datetime(2011, 1, 1, 4, 30, 0, tzinfo=EAT)],
transform=lambda d: d)
+ self.assertQuerysetEqual(Event.objects.datetimes('dt', 'second'),
+ [datetime.datetime(2011, 1, 1, 1, 30, 0, tzinfo=EAT),
+ datetime.datetime(2011, 1, 1, 4, 30, 0, tzinfo=EAT)],
+ transform=lambda d: d)
+
+ @skipUnlessDBFeature('has_zoneinfo_database')
+ def test_query_datetimes_in_other_timezone(self):
+ Event.objects.create(dt=datetime.datetime(2011, 1, 1, 1, 30, 0, tzinfo=EAT))
+ Event.objects.create(dt=datetime.datetime(2011, 1, 1, 4, 30, 0, tzinfo=EAT))
+ with timezone.override(UTC):
+ self.assertQuerysetEqual(Event.objects.datetimes('dt', 'year'),
+ [datetime.datetime(2010, 1, 1, 0, 0, 0, tzinfo=UTC),
+ datetime.datetime(2011, 1, 1, 0, 0, 0, tzinfo=UTC)],
+ transform=lambda d: d)
+ self.assertQuerysetEqual(Event.objects.datetimes('dt', 'month'),
+ [datetime.datetime(2010, 12, 1, 0, 0, 0, tzinfo=UTC),
+ datetime.datetime(2011, 1, 1, 0, 0, 0, tzinfo=UTC)],
+ transform=lambda d: d)
+ self.assertQuerysetEqual(Event.objects.datetimes('dt', 'day'),
+ [datetime.datetime(2010, 12, 31, 0, 0, 0, tzinfo=UTC),
+ datetime.datetime(2011, 1, 1, 0, 0, 0, tzinfo=UTC)],
+ transform=lambda d: d)
+ self.assertQuerysetEqual(Event.objects.datetimes('dt', 'hour'),
+ [datetime.datetime(2010, 12, 31, 22, 0, 0, tzinfo=UTC),
+ datetime.datetime(2011, 1, 1, 1, 0, 0, tzinfo=UTC)],
+ transform=lambda d: d)
+ self.assertQuerysetEqual(Event.objects.datetimes('dt', 'minute'),
+ [datetime.datetime(2010, 12, 31, 22, 30, 0, tzinfo=UTC),
+ datetime.datetime(2011, 1, 1, 1, 30, 0, tzinfo=UTC)],
+ transform=lambda d: d)
+ self.assertQuerysetEqual(Event.objects.datetimes('dt', 'second'),
+ [datetime.datetime(2010, 12, 31, 22, 30, 0, tzinfo=UTC),
+ datetime.datetime(2011, 1, 1, 1, 30, 0, tzinfo=UTC)],
+ transform=lambda d: d)
def test_raw_sql(self):
# Regression test for #17755
@@ -146,9 +146,9 @@ def test_django_date_trunc(self):
years = models.SchoolClass.objects.dates('last_updated', 'year')
self.assertEqual(list(years), [datetime.datetime(2010, 1, 1, 0, 0)])
- def test_django_extract(self):
+ def test_django_date_extract(self):
"""
- Test the custom ``django_extract method``, in particular against fields
+ Test the custom ``django_date_extract method``, in particular against fields
which clash with strings passed to it (e.g. 'day') - see #12818__.
__: http://code.djangoproject.com/ticket/12818
@@ -1,3 +1,5 @@
+from __future__ import unicode_literals
+
from django.db import models
from django.utils.encoding import python_2_unicode_compatible
@@ -1,6 +1,6 @@
from __future__ import absolute_import
-from datetime import datetime
+import datetime
from django.test import TestCase
@@ -11,64 +11,64 @@ class DatesTests(TestCase):
def test_related_model_traverse(self):
a1 = Article.objects.create(
title="First one",
- pub_date=datetime(2005, 7, 28),
+ pub_date=datetime.date(2005, 7, 28),
)
a2 = Article.objects.create(
title="Another one",
- pub_date=datetime(2010, 7, 28),
+ pub_date=datetime.date(2010, 7, 28),
)
a3 = Article.objects.create(
title="Third one, in the first day",
- pub_date=datetime(2005, 7, 28),
+ pub_date=datetime.date(2005, 7, 28),
)
a1.comments.create(
text="Im the HULK!",
- pub_date=datetime(2005, 7, 28),
+ pub_date=datetime.date(2005, 7, 28),
)
a1.comments.create(
text="HULK SMASH!",
- pub_date=datetime(2005, 7, 29),
+ pub_date=datetime.date(2005, 7, 29),
)
a2.comments.create(
text="LMAO",
- pub_date=datetime(2010, 7, 28),
+ pub_date=datetime.date(2010, 7, 28),
)
a3.comments.create(
text="+1",
- pub_date=datetime(2005, 8, 29),
+ pub_date=datetime.date(2005, 8, 29),
)
c = Category.objects.create(name="serious-news")
c.articles.add(a1, a3)
self.assertQuerysetEqual(
Comment.objects.dates("article__pub_date", "year"), [
- datetime(2005, 1, 1),
- datetime(2010, 1, 1),
+ datetime.date(2005, 1, 1),
+ datetime.date(2010, 1, 1),
],
lambda d: d,
)
self.assertQuerysetEqual(
Comment.objects.dates("article__pub_date", "month"), [
- datetime(2005, 7, 1),
- datetime(2010, 7, 1),
+ datetime.date(2005, 7, 1),
+ datetime.date(2010, 7, 1),
],
lambda d: d
)
self.assertQuerysetEqual(
Comment.objects.dates("article__pub_date", "day"), [
- datetime(2005, 7, 28),
- datetime(2010, 7, 28),
+ datetime.date(2005, 7, 28),
+ datetime.date(2010, 7, 28),
],
lambda d: d
)
self.assertQuerysetEqual(
Article.objects.dates("comments__pub_date", "day"), [
- datetime(2005, 7, 28),
- datetime(2005, 7, 29),
- datetime(2005, 8, 29),
- datetime(2010, 7, 28),
+ datetime.date(2005, 7, 28),
+ datetime.date(2005, 7, 29),
+ datetime.date(2005, 8, 29),
+ datetime.date(2010, 7, 28),
],
lambda d: d
)
@@ -77,7 +77,7 @@ def test_related_model_traverse(self):
)
self.assertQuerysetEqual(
Category.objects.dates("articles__pub_date", "day"), [
- datetime(2005, 7, 28),
+ datetime.date(2005, 7, 28),
],
lambda d: d,
)
@@ -0,0 +1,28 @@
+from __future__ import unicode_literals
+
+from django.db import models
+from django.utils.encoding import python_2_unicode_compatible
+
+
+@python_2_unicode_compatible
+class Article(models.Model):
+ title = models.CharField(max_length=100)
+ pub_date = models.DateTimeField()
+
+ categories = models.ManyToManyField("Category", related_name="articles")
+
+ def __str__(self):
+ return self.title
+
+@python_2_unicode_compatible
+class Comment(models.Model):
+ article = models.ForeignKey(Article, related_name="comments")
+ text = models.TextField()
+ pub_date = models.DateTimeField()
+ approval_date = models.DateTimeField(null=True)
+
+ def __str__(self):
+ return 'Comment to %s (%s)' % (self.article.title, self.pub_date)
+
+class Category(models.Model):
+ name = models.CharField(max_length=255)
Oops, something went wrong. Retry.

0 comments on commit 50fb7a5

Please sign in to comment.