mirror of
https://github.com/django/django.git
synced 2025-07-24 13:44:32 +00:00
Thanks Josh for the amazing testing setup and Tim for the review.
This commit is contained in:
parent
90468079ec
commit
082c52dbed
11 changed files with 245 additions and 35 deletions
|
@ -5,7 +5,7 @@ from unittest import skipIf
|
|||
|
||||
from django.conf import settings
|
||||
from django.db import connection
|
||||
from django.db.models import DateField, DateTimeField, IntegerField
|
||||
from django.db.models import DateField, DateTimeField, IntegerField, TimeField
|
||||
from django.db.models.functions import (
|
||||
Extract, ExtractDay, ExtractHour, ExtractMinute, ExtractMonth,
|
||||
ExtractSecond, ExtractWeekDay, ExtractYear, Trunc, TruncDate, TruncDay,
|
||||
|
@ -353,18 +353,25 @@ class DateFunctionTests(TestCase):
|
|||
self.create_model(start_datetime, end_datetime)
|
||||
self.create_model(end_datetime, start_datetime)
|
||||
|
||||
with self.assertRaisesMessage(ValueError, 'output_field must be either DateField or DateTimeField'):
|
||||
msg = 'output_field must be either DateField, TimeField, or DateTimeField'
|
||||
with self.assertRaisesMessage(ValueError, msg):
|
||||
list(DTModel.objects.annotate(truncated=Trunc('start_datetime', 'year', output_field=IntegerField())))
|
||||
|
||||
with self.assertRaisesMessage(AssertionError, "'name' isn't a DateField or DateTimeField."):
|
||||
with self.assertRaisesMessage(AssertionError, "'name' isn't a DateField, TimeField, or DateTimeField."):
|
||||
list(DTModel.objects.annotate(truncated=Trunc('name', 'year', output_field=DateTimeField())))
|
||||
|
||||
with self.assertRaisesMessage(ValueError, "Cannot truncate DateField 'start_date' to DateTimeField"):
|
||||
list(DTModel.objects.annotate(truncated=Trunc('start_date', 'second')))
|
||||
|
||||
with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField"):
|
||||
list(DTModel.objects.annotate(truncated=Trunc('start_time', 'month')))
|
||||
|
||||
with self.assertRaisesMessage(ValueError, "Cannot truncate DateField 'start_date' to DateTimeField"):
|
||||
list(DTModel.objects.annotate(truncated=Trunc('start_date', 'month', output_field=DateTimeField())))
|
||||
|
||||
with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField"):
|
||||
list(DTModel.objects.annotate(truncated=Trunc('start_time', 'second', output_field=DateTimeField())))
|
||||
|
||||
def test_datetime_kind(kind):
|
||||
self.assertQuerysetEqual(
|
||||
DTModel.objects.annotate(
|
||||
|
@ -389,9 +396,24 @@ class DateFunctionTests(TestCase):
|
|||
lambda m: (m.start_datetime, m.truncated)
|
||||
)
|
||||
|
||||
def test_time_kind(kind):
|
||||
self.assertQuerysetEqual(
|
||||
DTModel.objects.annotate(
|
||||
truncated=Trunc('start_time', kind, output_field=TimeField())
|
||||
).order_by('start_datetime'),
|
||||
[
|
||||
(start_datetime, truncate_to(start_datetime.time(), kind)),
|
||||
(end_datetime, truncate_to(end_datetime.time(), kind))
|
||||
],
|
||||
lambda m: (m.start_datetime, m.truncated)
|
||||
)
|
||||
|
||||
test_date_kind('year')
|
||||
test_date_kind('month')
|
||||
test_date_kind('day')
|
||||
test_time_kind('hour')
|
||||
test_time_kind('minute')
|
||||
test_time_kind('second')
|
||||
test_datetime_kind('year')
|
||||
test_datetime_kind('month')
|
||||
test_datetime_kind('day')
|
||||
|
@ -428,6 +450,12 @@ class DateFunctionTests(TestCase):
|
|||
)
|
||||
self.assertEqual(DTModel.objects.filter(start_datetime=TruncYear('start_datetime')).count(), 1)
|
||||
|
||||
with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField"):
|
||||
list(DTModel.objects.annotate(truncated=TruncYear('start_time')))
|
||||
|
||||
with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField"):
|
||||
list(DTModel.objects.annotate(truncated=TruncYear('start_time', output_field=TimeField())))
|
||||
|
||||
def test_trunc_month_func(self):
|
||||
start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321))
|
||||
end_datetime = truncate_to(microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123)), 'month')
|
||||
|
@ -454,6 +482,12 @@ class DateFunctionTests(TestCase):
|
|||
)
|
||||
self.assertEqual(DTModel.objects.filter(start_datetime=TruncMonth('start_datetime')).count(), 1)
|
||||
|
||||
with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField"):
|
||||
list(DTModel.objects.annotate(truncated=TruncMonth('start_time')))
|
||||
|
||||
with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField"):
|
||||
list(DTModel.objects.annotate(truncated=TruncMonth('start_time', output_field=TimeField())))
|
||||
|
||||
def test_trunc_date_func(self):
|
||||
start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321))
|
||||
end_datetime = microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123))
|
||||
|
@ -472,6 +506,12 @@ class DateFunctionTests(TestCase):
|
|||
)
|
||||
self.assertEqual(DTModel.objects.filter(start_datetime__date=TruncDate('start_datetime')).count(), 2)
|
||||
|
||||
with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateField"):
|
||||
list(DTModel.objects.annotate(truncated=TruncDate('start_time')))
|
||||
|
||||
with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateField"):
|
||||
list(DTModel.objects.annotate(truncated=TruncDate('start_time', output_field=TimeField())))
|
||||
|
||||
def test_trunc_day_func(self):
|
||||
start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321))
|
||||
end_datetime = truncate_to(microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123)), 'day')
|
||||
|
@ -490,6 +530,12 @@ class DateFunctionTests(TestCase):
|
|||
)
|
||||
self.assertEqual(DTModel.objects.filter(start_datetime=TruncDay('start_datetime')).count(), 1)
|
||||
|
||||
with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField"):
|
||||
list(DTModel.objects.annotate(truncated=TruncDay('start_time')))
|
||||
|
||||
with self.assertRaisesMessage(ValueError, "Cannot truncate TimeField 'start_time' to DateTimeField"):
|
||||
list(DTModel.objects.annotate(truncated=TruncDay('start_time', output_field=TimeField())))
|
||||
|
||||
def test_trunc_hour_func(self):
|
||||
start_datetime = microsecond_support(datetime(2015, 6, 15, 14, 30, 50, 321))
|
||||
end_datetime = truncate_to(microsecond_support(datetime(2016, 6, 15, 14, 10, 50, 123)), 'hour')
|
||||
|
@ -506,6 +552,14 @@ class DateFunctionTests(TestCase):
|
|||
],
|
||||
lambda m: (m.start_datetime, m.extracted)
|
||||
)
|
||||
self.assertQuerysetEqual(
|
||||
DTModel.objects.annotate(extracted=TruncHour('start_time')).order_by('start_datetime'),
|
||||
[
|
||||
(start_datetime, truncate_to(start_datetime.time(), 'hour')),
|
||||
(end_datetime, truncate_to(end_datetime.time(), 'hour')),
|
||||
],
|
||||
lambda m: (m.start_datetime, m.extracted)
|
||||
)
|
||||
self.assertEqual(DTModel.objects.filter(start_datetime=TruncHour('start_datetime')).count(), 1)
|
||||
|
||||
with self.assertRaisesMessage(ValueError, "Cannot truncate DateField 'start_date' to DateTimeField"):
|
||||
|
@ -530,6 +584,14 @@ class DateFunctionTests(TestCase):
|
|||
],
|
||||
lambda m: (m.start_datetime, m.extracted)
|
||||
)
|
||||
self.assertQuerysetEqual(
|
||||
DTModel.objects.annotate(extracted=TruncMinute('start_time')).order_by('start_datetime'),
|
||||
[
|
||||
(start_datetime, truncate_to(start_datetime.time(), 'minute')),
|
||||
(end_datetime, truncate_to(end_datetime.time(), 'minute')),
|
||||
],
|
||||
lambda m: (m.start_datetime, m.extracted)
|
||||
)
|
||||
self.assertEqual(DTModel.objects.filter(start_datetime=TruncMinute('start_datetime')).count(), 1)
|
||||
|
||||
with self.assertRaisesMessage(ValueError, "Cannot truncate DateField 'start_date' to DateTimeField"):
|
||||
|
@ -554,6 +616,14 @@ class DateFunctionTests(TestCase):
|
|||
],
|
||||
lambda m: (m.start_datetime, m.extracted)
|
||||
)
|
||||
self.assertQuerysetEqual(
|
||||
DTModel.objects.annotate(extracted=TruncSecond('start_time')).order_by('start_datetime'),
|
||||
[
|
||||
(start_datetime, truncate_to(start_datetime.time(), 'second')),
|
||||
(end_datetime, truncate_to(end_datetime.time(), 'second'))
|
||||
],
|
||||
lambda m: (m.start_datetime, m.extracted)
|
||||
)
|
||||
|
||||
result = 1 if connection.features.supports_microsecond_precision else 2
|
||||
self.assertEqual(DTModel.objects.filter(start_datetime=TruncSecond('start_datetime')).count(), result)
|
||||
|
@ -680,9 +750,24 @@ class DateFunctionWithTimeZoneTests(DateFunctionTests):
|
|||
lambda m: (m.start_datetime, m.truncated)
|
||||
)
|
||||
|
||||
def test_time_kind(kind, tzinfo=melb):
|
||||
self.assertQuerysetEqual(
|
||||
DTModel.objects.annotate(
|
||||
truncated=Trunc('start_time', kind, output_field=TimeField(), tzinfo=melb)
|
||||
).order_by('start_datetime'),
|
||||
[
|
||||
(start_datetime, truncate_to(start_datetime.time(), kind)),
|
||||
(end_datetime, truncate_to(end_datetime.time(), kind))
|
||||
],
|
||||
lambda m: (m.start_datetime, m.truncated)
|
||||
)
|
||||
|
||||
test_date_kind('year')
|
||||
test_date_kind('month')
|
||||
test_date_kind('day')
|
||||
test_time_kind('hour')
|
||||
test_time_kind('minute')
|
||||
test_time_kind('second')
|
||||
test_datetime_kind('year')
|
||||
test_datetime_kind('month')
|
||||
test_datetime_kind('day')
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue