Fixed #7190. Boolean fields now return bool values instead of 1 or 0. Thanks, Alex Gaynor.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@12578 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
Joseph Kocherhans 2010-02-24 17:36:18 +00:00
parent 9f4bf525f8
commit 16fe73d918
5 changed files with 47 additions and 24 deletions

View File

@ -524,9 +524,14 @@ class BooleanField(Field):
return "BooleanField"
def to_python(self, value):
if value in (True, False): return value
if value in ('t', 'True', '1'): return True
if value in ('f', 'False', '0'): return False
if value in (True, False):
# if value is 1 or 0 than it's equal to True or False, but we want
# to return a true bool for semantic reasons.
return bool(value)
if value in ('t', 'True', '1'):
return True
if value in ('f', 'False', '0'):
return False
raise exceptions.ValidationError(self.error_messages['invalid'])
def get_prep_lookup(self, lookup_type, value):
@ -934,10 +939,16 @@ class NullBooleanField(Field):
return "NullBooleanField"
def to_python(self, value):
if value in (None, True, False): return value
if value in ('None',): return None
if value in ('t', 'True', '1'): return True
if value in ('f', 'False', '0'): return False
if value is None:
return None
if value in (True, False):
return bool(value)
if value in ('None',):
return None
if value in ('t', 'True', '1'):
return True
if value in ('f', 'False', '0'):
return False
raise exceptions.ValidationError(self.error_messages['invalid'])
def get_prep_lookup(self, lookup_type, value):

View File

@ -326,12 +326,11 @@ Notes on specific fields
Boolean fields
~~~~~~~~~~~~~~
Since MySQL doesn't have a direct ``BOOLEAN`` column type, Django uses a
``TINYINT`` column with values of ``1`` and ``0`` to store values for the
:class:`~django.db.models.BooleanField` model field. Refer to the documentation
of that field for more details, but usually this won't be something that will
matter unless you're printing out the field values and are expecting to see
``True`` and ``False.``.
.. versionchanged:: 1.2
In previous versions of Django when running under MySQL ``BooleanFields`` would
return their data as ``ints``, instead of true ``bools``. See the release
notes for a complete description of the change.
Character fields
~~~~~~~~~~~~~~~~

View File

@ -342,18 +342,11 @@ A true/false field.
The admin represents this as a checkbox.
.. admonition:: MySQL users..
.. versionchanged:: 1.2
A boolean field in MySQL is stored as a ``TINYINT`` column with a value of
either 0 or 1 (most databases have a proper ``BOOLEAN`` type instead). So,
for MySQL, only, when a ``BooleanField`` is retrieved from the database
and stored on a model attribute, it will have the values 1 or 0, rather
than ``True`` or ``False``. Normally, this shouldn't be a problem, since
Python guarantees that ``1 == True`` and ``0 == False`` are both true.
Just be careful if you're writing something like ``obj is True`` when
``obj`` is a value from a boolean attribute on a model. If that model was
constructed using the ``mysql`` backend, the "``is``" test will fail.
Prefer an equality test (using "``==``") in cases like this.
In previous versions of Django when running under MySQL ``BooleanFields``
would return their data as ``ints``, instead of true ``bools``. See the
release notes for a complete description of the change.
``CharField``
-------------

View File

@ -302,6 +302,16 @@ created using ``decorator_from_middleware``.
.. _deprecated-features-1.2:
``BooleanField`` on MySQL
--------------------------
In previous versions of Django ``BoleanFields`` under MySQL would return their
values as either ``1`` or ``0``, instead of ``True`` or ``False``. For most
people this shouldn't have been a problem because ``bool`` is a subclass of
``int``, however in Django 1.2 MySQL correctly returns a real ``bool``. The
only time this should ever be an issue is if you were expecting printing the
``repr`` of a ``BooleanField`` to print ``1`` or ``0``.
Features deprecated in 1.2
==========================

View File

@ -108,12 +108,22 @@ class BooleanFieldTests(unittest.TestCase):
self.assertEqual(f.get_db_prep_lookup('exact', 0, connection=connection), [False])
self.assertEqual(f.get_db_prep_lookup('exact', None, connection=connection), [None])
def _test_to_python(self, f):
self.assertTrue(f.to_python(1) is True)
self.assertTrue(f.to_python(0) is False)
def test_booleanfield_get_db_prep_lookup(self):
self._test_get_db_prep_lookup(models.BooleanField())
def test_nullbooleanfield_get_db_prep_lookup(self):
self._test_get_db_prep_lookup(models.NullBooleanField())
def test_booleanfield_to_python(self):
self._test_to_python(models.BooleanField())
def test_nullbooleanfield_to_python(self):
self._test_to_python(models.NullBooleanField())
def test_booleanfield_choices_blank(self):
"""
Test that BooleanField with choices and defaults doesn't generate a