test_booleanfield.py 4.26 KB
Newer Older
1
from django.core.exceptions import ValidationError
2
from django.db import IntegrityError, models, transaction
3 4 5 6 7 8
from django.test import SimpleTestCase, TestCase

from .models import BooleanModel, FksToBooleans, NullBooleanModel


class BooleanFieldTests(TestCase):
9
    def _test_get_prep_value(self, f):
10 11 12 13 14 15 16
        self.assertIs(f.get_prep_value(True), True)
        self.assertIs(f.get_prep_value('1'), True)
        self.assertIs(f.get_prep_value(1), True)
        self.assertIs(f.get_prep_value(False), False)
        self.assertIs(f.get_prep_value('0'), False)
        self.assertIs(f.get_prep_value(0), False)
        self.assertIsNone(f.get_prep_value(None))
17 18 19 20 21

    def _test_to_python(self, f):
        self.assertIs(f.to_python(1), True)
        self.assertIs(f.to_python(0), False)

22 23
    def test_booleanfield_get_prep_value(self):
        self._test_get_prep_value(models.BooleanField())
24

25 26
    def test_nullbooleanfield_get_prep_value(self):
        self._test_get_prep_value(models.NullBooleanField())
27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45

    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):
        """
        BooleanField with choices and defaults doesn't generate a formfield
        with the blank option (#9640, #10549).
        """
        choices = [(1, 'Si'), (2, 'No')]
        f = models.BooleanField(choices=choices, default=1, null=False)
        self.assertEqual(f.formfield().choices, choices)

    def test_return_type(self):
        b = BooleanModel.objects.create(bfield=True)
        b.refresh_from_db()
46
        self.assertIs(b.bfield, True)
47 48 49

        b2 = BooleanModel.objects.create(bfield=False)
        b2.refresh_from_db()
50
        self.assertIs(b2.bfield, False)
51 52 53

        b3 = NullBooleanModel.objects.create(nbfield=True)
        b3.refresh_from_db()
54
        self.assertIs(b3.nbfield, True)
55 56 57

        b4 = NullBooleanModel.objects.create(nbfield=False)
        b4.refresh_from_db()
58
        self.assertIs(b4.nbfield, False)
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77

        # When an extra clause exists, the boolean conversions are applied with
        # an offset (#13293).
        b5 = BooleanModel.objects.all().extra(select={'string_col': 'string'})[0]
        self.assertNotIsInstance(b5.pk, bool)

    def test_select_related(self):
        """
        Boolean fields retrieved via select_related() should return booleans.
        """
        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)

        # select_related('fk_field_name')
        ma = FksToBooleans.objects.select_related('bf').get(pk=m1.id)
78 79
        self.assertIs(ma.bf.bfield, True)
        self.assertIs(ma.nbf.nbfield, True)
80 81 82 83

        # select_related()
        mb = FksToBooleans.objects.select_related().get(pk=m1.id)
        mc = FksToBooleans.objects.select_related().get(pk=m2.id)
84 85 86 87
        self.assertIs(mb.bf.bfield, True)
        self.assertIs(mb.nbf.nbfield, True)
        self.assertIs(mc.bf.bfield, False)
        self.assertIs(mc.nbf.nbfield, False)
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119

    def test_null_default(self):
        """
        A BooleanField defaults to None, which isn't a valid value (#15124).
        """
        boolean_field = BooleanModel._meta.get_field('bfield')
        self.assertFalse(boolean_field.has_default())
        b = BooleanModel()
        self.assertIsNone(b.bfield)
        with transaction.atomic():
            with self.assertRaises(IntegrityError):
                b.save()

        nb = NullBooleanModel()
        self.assertIsNone(nb.nbfield)
        nb.save()  # no error


class ValidationTest(SimpleTestCase):

    def test_boolean_field_doesnt_accept_empty_input(self):
        f = models.BooleanField()
        with self.assertRaises(ValidationError):
            f.clean(None, None)

    def test_nullbooleanfield_blank(self):
        """
        NullBooleanField shouldn't throw a validation error when given a value
        of None.
        """
        nullboolean = NullBooleanModel(nbfield=None)
        nullboolean.full_clean()