Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Fixed #21798 -- Added check for DateTime mutually exclusive options

Added DateTimeCheckMixin to avoid the use of default, auto_now, and
auto_now_add options together. Added the fields.E151 Error that is raised
if one or more of these options are used together.
  • Loading branch information...
commit cb15231888df2545356ad307eaea07f36aa0e8e0 1 parent 8a9d54a
@PirosB3 PirosB3 authored timgraham committed
View
34 django/db/models/fields/__init__.py
@@ -1074,7 +1074,37 @@ def formfield(self, **kwargs):
return super(CommaSeparatedIntegerField, self).formfield(**defaults)
-class DateField(Field):
+class DateTimeCheckMixin(object):
+
+ def check(self, **kwargs):
+ errors = super(DateTimeCheckMixin, self).check(**kwargs)
+ errors.extend(self._check_mutually_exclusive_options())
+ return errors
+
+ def _check_mutually_exclusive_options(self):
+ # auto_now, auto_now_add, and default are mutually exclusive
+ # options. The use of more than one of these options together
+ # will trigger an Error
+ mutually_exclusive_options = [self.auto_now_add, self.auto_now,
+ self.has_default()]
+ enabled_options = [option not in (None, False)
+ for option in mutually_exclusive_options].count(True)
+ if enabled_options > 1:
+ return [
+ checks.Error(
+ "The options auto_now, auto_now_add, and default "
+ "are mutually exclusive. Only one of these options "
+ "may be present.",
+ hint=None,
+ obj=self,
+ id='fields.E151',
+ )
+ ]
+ else:
+ return []
+
+
+class DateField(DateTimeCheckMixin, Field):
empty_strings_allowed = False
default_error_messages = {
'invalid': _("'%(value)s' value has an invalid date format. It must be "
@@ -1887,7 +1917,7 @@ def formfield(self, **kwargs):
return super(TextField, self).formfield(**defaults)
-class TimeField(Field):
+class TimeField(DateTimeCheckMixin, Field):
empty_strings_allowed = False
default_error_messages = {
'invalid': _("'%(value)s' value has an invalid format. It must be in "
View
1  docs/ref/checks.txt
@@ -67,6 +67,7 @@ Fields
* **fields.E134**: ``max_digits`` must be greater or equal to ``decimal_places``.
* **fields.E140**: FilePathFields must have either ``allow_files`` or ``allow_folders`` set to True.
* **fields.E150**: GenericIPAddressFields cannot accept blank values if null values are not allowed, as blank values are stored as nulls.
+* **fields.E151**: The options ``auto_now``, ``auto_now_add``, and ``default`` are mutually exclusive. Only one of these options may be present.
File Fields
~~~~~~~~~~~
View
3  docs/ref/models/fields.txt
@@ -477,6 +477,9 @@ The default form widget for this field is a
and a shortcut for "Today". Includes an additional ``invalid_date`` error
message key.
+The options ``auto_now_add``, ``auto_now``, and ``default`` are mutually exclusive.
+Any combination of these options will result in an error.
+
.. note::
As currently implemented, setting ``auto_now`` or ``auto_now_add`` to
``True`` will cause the field to have ``editable=False`` and ``blank=True``
View
28 tests/invalid_models_tests/test_ordinary_fields.py
@@ -1,6 +1,7 @@
# -*- encoding: utf-8 -*-
from __future__ import unicode_literals
+from datetime import datetime
import unittest
from django.core.checks import Error
@@ -399,3 +400,30 @@ class Model(models.Model):
),
]
self.assertEqual(errors, expected)
+
+
+class DateFieldTests(IsolatedModelsTestCase):
+
+ def test_auto_now_and_auto_now_add_raise_error(self):
+ dn = datetime.now
+ mutually_exclusive_combinations = (
+ (True, True, dn),
+ (True, False, dn),
+ (False, True, dn),
+ (True, True, None)
+ )
+
+ for auto_now, auto_now_add, default in mutually_exclusive_combinations:
+ field = models.DateTimeField(name="field", auto_now=auto_now,
+ auto_now_add=auto_now_add,
+ default=default)
+ expected = [Error(
+ "The options auto_now, auto_now_add, and default "
+ "are mutually exclusive. Only one of these options "
+ "may be present.",
+ hint=None,
+ obj=field,
+ id='fields.E151',
+ )]
+ checks = field.check()
+ self.assertEqual(checks, expected)
Please sign in to comment.
Something went wrong with that request. Please try again.