mirror of https://github.com/django/django.git
Fixed #15040 - Boolean fields return 0 and 1 when loaded through select_related
Thanks to homm for the report and ramiro for the patch.
This commit is contained in:
parent
5c143cb340
commit
f3a2bcdee9
|
@ -774,10 +774,20 @@ class SQLCompiler(object):
|
|||
# We only set this up here because
|
||||
# related_select_fields isn't populated until
|
||||
# execute_sql() has been called.
|
||||
|
||||
# We also include types of fields of related models that
|
||||
# will be included via select_related() for the benefit
|
||||
# of MySQL/MySQLdb when boolean fields are involved
|
||||
# (#15040).
|
||||
|
||||
# This code duplicates the logic for the order of fields
|
||||
# found in get_columns(). It would be nice to clean this up.
|
||||
if self.query.select_fields:
|
||||
fields = self.query.select_fields + self.query.related_select_fields
|
||||
fields = self.query.select_fields
|
||||
else:
|
||||
fields = self.query.model._meta.fields
|
||||
fields = fields + self.query.related_select_fields
|
||||
|
||||
# If the field was deferred, exclude it from being passed
|
||||
# into `resolve_columns` because it wasn't selected.
|
||||
only_load = self.deferred_to_columns()
|
||||
|
|
|
@ -66,6 +66,11 @@ class BooleanModel(models.Model):
|
|||
bfield = models.BooleanField()
|
||||
string = models.CharField(max_length=10, default='abc')
|
||||
|
||||
class FksToBooleans(models.Model):
|
||||
"""Model wih FKs to models with {Null,}BooleanField's, #15040"""
|
||||
bf = models.ForeignKey(BooleanModel)
|
||||
nbf = models.ForeignKey(NullBooleanModel)
|
||||
|
||||
class RenamedField(models.Model):
|
||||
modelname = models.IntegerField(name="fieldname", choices=((1,'One'),))
|
||||
|
||||
|
|
|
@ -12,7 +12,8 @@ from django.utils import six
|
|||
from django.utils import unittest
|
||||
|
||||
from .models import (Foo, Bar, Whiz, BigD, BigS, Image, BigInt, Post,
|
||||
NullBooleanModel, BooleanModel, Document, RenamedField, VerboseNameField)
|
||||
NullBooleanModel, BooleanModel, Document, RenamedField, VerboseNameField,
|
||||
FksToBooleans)
|
||||
|
||||
from .imagefield import (ImageFieldTests, ImageFieldTwoDimensionsTests,
|
||||
TwoImageFieldTests, ImageFieldNoDimensionsTests,
|
||||
|
@ -218,6 +219,43 @@ class BooleanFieldTests(unittest.TestCase):
|
|||
select={'string_col': 'string'})[0]
|
||||
self.assertFalse(isinstance(b5.pk, bool))
|
||||
|
||||
def test_select_related(self):
|
||||
"""
|
||||
Test type of boolean fields when retrieved via select_related() (MySQL,
|
||||
#15040)
|
||||
"""
|
||||
bmt = BooleanModel.objects.create(bfield=True)
|
||||
bmf = BooleanModel.objects.create(bfield=False)
|
||||
nbmt = NullBooleanModel.objects.create(nbfield=True)
|
||||
nbmf = NullBooleanModel.objects.create(nbfield=False)
|
||||
|
||||
m1 = FksToBooleans.objects.create(bf=bmt, nbf=nbmt)
|
||||
m2 = FksToBooleans.objects.create(bf=bmf, nbf=nbmf)
|
||||
|
||||
# Test select_related('fk_field_name')
|
||||
ma = FksToBooleans.objects.select_related('bf').get(pk=m1.id)
|
||||
# verify types -- should't be 0/1
|
||||
self.assertIsInstance(ma.bf.bfield, bool)
|
||||
self.assertIsInstance(ma.nbf.nbfield, bool)
|
||||
# verify values
|
||||
self.assertEqual(ma.bf.bfield, True)
|
||||
self.assertEqual(ma.nbf.nbfield, True)
|
||||
|
||||
# Test select_related()
|
||||
mb = FksToBooleans.objects.select_related().get(pk=m1.id)
|
||||
mc = FksToBooleans.objects.select_related().get(pk=m2.id)
|
||||
# verify types -- shouldn't be 0/1
|
||||
self.assertIsInstance(mb.bf.bfield, bool)
|
||||
self.assertIsInstance(mb.nbf.nbfield, bool)
|
||||
self.assertIsInstance(mc.bf.bfield, bool)
|
||||
self.assertIsInstance(mc.nbf.nbfield, bool)
|
||||
# verify values
|
||||
self.assertEqual(mb.bf.bfield, True)
|
||||
self.assertEqual(mb.nbf.nbfield, True)
|
||||
self.assertEqual(mc.bf.bfield, False)
|
||||
self.assertEqual(mc.nbf.nbfield, False)
|
||||
|
||||
|
||||
class ChoicesTests(test.TestCase):
|
||||
def test_choices_and_field_display(self):
|
||||
"""
|
||||
|
|
Loading…
Reference in New Issue