Fixed #15124 -- Changed the default for BooleanField.

Thanks to the many contributors who updated and improved the patch over
the life of this ticket.
This commit is contained in:
Aymeric Augustin 2013-03-24 13:47:01 +01:00
parent ae417dd4d5
commit e16c48e001
6 changed files with 37 additions and 7 deletions

View File

@ -11,10 +11,12 @@ class FlatPage(models.Model):
url = models.CharField(_('URL'), max_length=100, db_index=True)
title = models.CharField(_('title'), max_length=200)
content = models.TextField(_('content'), blank=True)
enable_comments = models.BooleanField(_('enable comments'))
enable_comments = models.BooleanField(_('enable comments'), default=False)
template_name = models.CharField(_('template name'), max_length=70, blank=True,
help_text=_("Example: 'flatpages/contact_page.html'. If this isn't provided, the system will use 'flatpages/default.html'."))
registration_required = models.BooleanField(_('registration required'), help_text=_("If this is checked, only logged-in users will be able to view the page."))
registration_required = models.BooleanField(_('registration required'),
help_text=_("If this is checked, only logged-in users will be able to view the page."),
default=False)
sites = models.ManyToManyField(Site)
class Meta:

View File

@ -620,8 +620,6 @@ class BooleanField(Field):
def __init__(self, *args, **kwargs):
kwargs['blank'] = True
if 'default' not in kwargs and not kwargs.get('null'):
kwargs['default'] = False
Field.__init__(self, *args, **kwargs)
def get_internal_type(self):

View File

@ -377,6 +377,10 @@ The default form widget for this field is a
If you need to accept :attr:`~Field.null` values then use
:class:`NullBooleanField` instead.
.. versionchanged:: 1.6
The default value of ``BooleanField`` was changed from ``False`` to
``None`` when :attr:`Field.default` isn't defined.
``CharField``
-------------

View File

@ -292,6 +292,20 @@ should either restore Django's defaults at the end of each request, force an
appropriate value at the beginning of each request, or disable persistent
connections.
``BooleanField`` no longer defaults to ``False``
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
When a :class:`~django.db.models.BooleanField` doesn't have an explicit
:attr:`~django.db.models.Field.default`, the implicit default value is
``None``. In previous version of Django, it was ``False``, but that didn't
represent accurantely the lack of a value.
Code that relies on the default value being ``False`` may raise an exception
when saving new model instances to the database, because ``None`` isn't an
acceptable value for a :class:`~django.db.models.BooleanField`. You should
either specify ``default=False`` explicitly on the field definition, or ensure
the field is set to ``True`` or ``False`` before saving the object.
Translations and comments in templates
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

View File

@ -6,7 +6,7 @@ from decimal import Decimal
from django import test
from django import forms
from django.core.exceptions import ValidationError
from django.db import models
from django.db import models, IntegrityError
from django.db.models.fields.files import FieldFile
from django.utils import six
from django.utils import unittest
@ -265,6 +265,18 @@ class BooleanFieldTests(unittest.TestCase):
self.assertEqual(mc.bf.bfield, False)
self.assertEqual(mc.nbf.nbfield, False)
def test_null_default(self):
"""
Check that a BooleanField defaults to None -- which isn't
a valid value (#15124).
"""
b = BooleanModel()
self.assertIsNone(b.bfield)
with self.assertRaises(IntegrityError):
b.save()
nb = NullBooleanModel()
self.assertIsNone(nb.nbfield)
nb.save() # no error
class ChoicesTests(test.TestCase):
def test_choices_and_field_display(self):

View File

@ -181,11 +181,11 @@ class ModelInheritanceTest(TestCase):
"""
Regression test for #6755
"""
r = Restaurant(serves_pizza=False)
r = Restaurant(serves_pizza=False, serves_hot_dogs=False)
r.save()
self.assertEqual(r.id, r.place_ptr_id)
orig_id = r.id
r = Restaurant(place_ptr_id=orig_id, serves_pizza=True)
r = Restaurant(place_ptr_id=orig_id, serves_pizza=True, serves_hot_dogs=False)
r.save()
self.assertEqual(r.id, orig_id)
self.assertEqual(r.id, r.place_ptr_id)