From 6f5e07a84d65496abcdb876170c513c4a3840760 Mon Sep 17 00:00:00 2001 From: Chris Jerdonek Date: Thu, 29 Jul 2021 01:47:24 -0400 Subject: [PATCH] Refs #32966 -- Refactored out DateTimeCheckMixin._check_if_value_fixed(). --- django/db/models/fields/__init__.py | 109 +++++++++++----------------- 1 file changed, 42 insertions(+), 67 deletions(-) diff --git a/django/db/models/fields/__init__.py b/django/db/models/fields/__init__.py index 676a00acfd..1e8637d2f7 100644 --- a/django/db/models/fields/__init__.py +++ b/django/db/models/fields/__init__.py @@ -1144,6 +1144,42 @@ class DateTimeCheckMixin: def _check_fix_default_value(self): return [] + # Concrete subclasses use this in their implementations of + # _check_fix_default_value(). + def _check_if_value_fixed(self, value, now=None): + """ + Check if the given value appears to have been provided as a "fixed" + time value, and include a warning in the returned list if it does. The + value argument must be a date object or aware/naive datetime object. If + now is provided, it must be a naive datetime object. + """ + if now is None: + now = _get_naive_now() + offset = datetime.timedelta(seconds=10) + lower = now - offset + upper = now + offset + if isinstance(value, datetime.datetime): + value = _to_naive(value) + else: + assert isinstance(value, datetime.date) + lower = lower.date() + upper = upper.date() + if lower <= value <= upper: + return [ + checks.Warning( + 'Fixed default value provided.', + hint=( + 'It seems you set a fixed date / time / datetime ' + 'value as default for this field. This may not be ' + 'what you want. If you want to have the current date ' + 'as default, use `django.utils.timezone.now`' + ), + obj=self, + id='fields.W161', + ) + ] + return [] + class DateField(DateTimeCheckMixin, Field): empty_strings_allowed = False @@ -1175,30 +1211,12 @@ class DateField(DateTimeCheckMixin, Field): if isinstance(value, datetime.datetime): value = _to_naive(value).date() elif isinstance(value, datetime.date): - # Nothing to do, as dates don't have tz information pass else: # No explicit date / datetime value -- no checks necessary return [] # At this point, value is a date object. - today = _get_naive_now().date() - offset = datetime.timedelta(days=1) - lower = today - offset - upper = today + offset - if lower <= value <= upper: - return [ - checks.Warning( - 'Fixed default value provided.', - hint='It seems you set a fixed date / time / datetime ' - 'value as default for this field. This may not be ' - 'what you want. If you want to have the current date ' - 'as default, use `django.utils.timezone.now`', - obj=self, - id='fields.W161', - ) - ] - - return [] + return self._check_if_value_fixed(value) def deconstruct(self): name, path, args, kwargs = super().deconstruct() @@ -1309,35 +1327,9 @@ class DateTimeField(DateField): return [] value = self.default - if isinstance(value, datetime.datetime): - value = _to_naive(value) - now = _get_naive_now() - offset = datetime.timedelta(seconds=10) - lower = now - offset - upper = now + offset - elif isinstance(value, datetime.date): - now = _get_naive_now() - offset = datetime.timedelta(seconds=10) - lower = now - offset - upper = now + offset - lower = lower.date() - upper = upper.date() - else: - # No explicit date / datetime value -- no checks necessary - return [] - if lower <= value <= upper: - return [ - checks.Warning( - 'Fixed default value provided.', - hint='It seems you set a fixed date / time / datetime ' - 'value as default for this field. This may not be ' - 'what you want. If you want to have the current date ' - 'as default, use `django.utils.timezone.now`', - obj=self, - id='fields.W161', - ) - ] - + if isinstance(value, (datetime.datetime, datetime.date)): + return self._check_if_value_fixed(value) + # No explicit date / datetime value -- no checks necessary. return [] def get_internal_type(self): @@ -2203,7 +2195,7 @@ class TimeField(DateTimeCheckMixin, Field): value = self.default if isinstance(value, datetime.datetime): - now = _get_naive_now() + now = None elif isinstance(value, datetime.time): now = _get_naive_now() # This will not use the right date in the race condition where now @@ -2213,24 +2205,7 @@ class TimeField(DateTimeCheckMixin, Field): # No explicit time / datetime value -- no checks necessary return [] # At this point, value is a datetime object. - offset = datetime.timedelta(seconds=10) - lower = now - offset - upper = now + offset - value = _to_naive(value) - if lower <= value <= upper: - return [ - checks.Warning( - 'Fixed default value provided.', - hint='It seems you set a fixed date / time / datetime ' - 'value as default for this field. This may not be ' - 'what you want. If you want to have the current date ' - 'as default, use `django.utils.timezone.now`', - obj=self, - id='fields.W161', - ) - ] - - return [] + return self._check_if_value_fixed(value, now=now) def deconstruct(self): name, path, args, kwargs = super().deconstruct()