diff --git a/django/db/models/sql/compiler.py b/django/db/models/sql/compiler.py
--- a/django/db/models/sql/compiler.py
+++ b/django/db/models/sql/compiler.py
@@ -767,10 +767,15 @@
                         # 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)
                         if self.query.select_fields:
                             fields = self.query.select_fields + self.query.related_select_fields
                         else:
-                            fields = self.query.model._meta.fields
+                            fields = self.query.model._meta.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()
diff --git a/tests/regressiontests/model_fields/models.py b/tests/regressiontests/model_fields/models.py
--- a/tests/regressiontests/model_fields/models.py
+++ b/tests/regressiontests/model_fields/models.py
@@ -66,6 +66,11 @@
     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'),))
 
diff --git a/tests/regressiontests/model_fields/tests.py b/tests/regressiontests/model_fields/tests.py
--- a/tests/regressiontests/model_fields/tests.py
+++ b/tests/regressiontests/model_fields/tests.py
@@ -11,7 +11,7 @@
 from django.utils import unittest
 
 from .models import (Foo, Bar, Whiz, BigD, BigS, Image, BigInt, Post,
-    NullBooleanModel, BooleanModel, Document, RenamedField)
+    NullBooleanModel, BooleanModel, Document, RenamedField, FksToBooleans)
 
 # If PIL available, do these tests.
 if Image:
@@ -211,6 +211,42 @@
             select={'string_length': 'LENGTH(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):
         """
