Refs #31369 -- Removed models.NullBooleanField per deprecation timeline.
This commit is contained in:
parent
06eec31970
commit
d992f4e3c2
|
@ -119,7 +119,6 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
||||||
'IPAddressField': 'char(15)',
|
'IPAddressField': 'char(15)',
|
||||||
'GenericIPAddressField': 'char(39)',
|
'GenericIPAddressField': 'char(39)',
|
||||||
'JSONField': 'json',
|
'JSONField': 'json',
|
||||||
'NullBooleanField': 'bool',
|
|
||||||
'OneToOneField': 'integer',
|
'OneToOneField': 'integer',
|
||||||
'PositiveBigIntegerField': 'bigint UNSIGNED',
|
'PositiveBigIntegerField': 'bigint UNSIGNED',
|
||||||
'PositiveIntegerField': 'integer UNSIGNED',
|
'PositiveIntegerField': 'integer UNSIGNED',
|
||||||
|
|
|
@ -291,7 +291,7 @@ class DatabaseOperations(BaseDatabaseOperations):
|
||||||
def get_db_converters(self, expression):
|
def get_db_converters(self, expression):
|
||||||
converters = super().get_db_converters(expression)
|
converters = super().get_db_converters(expression)
|
||||||
internal_type = expression.output_field.get_internal_type()
|
internal_type = expression.output_field.get_internal_type()
|
||||||
if internal_type in ['BooleanField', 'NullBooleanField']:
|
if internal_type == 'BooleanField':
|
||||||
converters.append(self.convert_booleanfield_value)
|
converters.append(self.convert_booleanfield_value)
|
||||||
elif internal_type == 'DateTimeField':
|
elif internal_type == 'DateTimeField':
|
||||||
if settings.USE_TZ:
|
if settings.USE_TZ:
|
||||||
|
|
|
@ -127,7 +127,6 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
||||||
'BigIntegerField': 'NUMBER(19)',
|
'BigIntegerField': 'NUMBER(19)',
|
||||||
'IPAddressField': 'VARCHAR2(15)',
|
'IPAddressField': 'VARCHAR2(15)',
|
||||||
'GenericIPAddressField': 'VARCHAR2(39)',
|
'GenericIPAddressField': 'VARCHAR2(39)',
|
||||||
'NullBooleanField': 'NUMBER(1)',
|
|
||||||
'OneToOneField': 'NUMBER(11)',
|
'OneToOneField': 'NUMBER(11)',
|
||||||
'PositiveBigIntegerField': 'NUMBER(19)',
|
'PositiveBigIntegerField': 'NUMBER(19)',
|
||||||
'PositiveIntegerField': 'NUMBER(11)',
|
'PositiveIntegerField': 'NUMBER(11)',
|
||||||
|
@ -143,7 +142,6 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
||||||
data_type_check_constraints = {
|
data_type_check_constraints = {
|
||||||
'BooleanField': '%(qn_column)s IN (0,1)',
|
'BooleanField': '%(qn_column)s IN (0,1)',
|
||||||
'JSONField': '%(qn_column)s IS JSON',
|
'JSONField': '%(qn_column)s IS JSON',
|
||||||
'NullBooleanField': '%(qn_column)s IN (0,1)',
|
|
||||||
'PositiveBigIntegerField': '%(qn_column)s >= 0',
|
'PositiveBigIntegerField': '%(qn_column)s >= 0',
|
||||||
'PositiveIntegerField': '%(qn_column)s >= 0',
|
'PositiveIntegerField': '%(qn_column)s >= 0',
|
||||||
'PositiveSmallIntegerField': '%(qn_column)s >= 0',
|
'PositiveSmallIntegerField': '%(qn_column)s >= 0',
|
||||||
|
|
|
@ -182,7 +182,7 @@ END;
|
||||||
converters.append(self.convert_textfield_value)
|
converters.append(self.convert_textfield_value)
|
||||||
elif internal_type == 'BinaryField':
|
elif internal_type == 'BinaryField':
|
||||||
converters.append(self.convert_binaryfield_value)
|
converters.append(self.convert_binaryfield_value)
|
||||||
elif internal_type in ['BooleanField', 'NullBooleanField']:
|
elif internal_type == 'BooleanField':
|
||||||
converters.append(self.convert_booleanfield_value)
|
converters.append(self.convert_booleanfield_value)
|
||||||
elif internal_type == 'DateTimeField':
|
elif internal_type == 'DateTimeField':
|
||||||
if settings.USE_TZ:
|
if settings.USE_TZ:
|
||||||
|
|
|
@ -73,7 +73,6 @@ class BulkInsertMapper:
|
||||||
'DurationField': INTERVAL,
|
'DurationField': INTERVAL,
|
||||||
'FloatField': NUMBER,
|
'FloatField': NUMBER,
|
||||||
'IntegerField': NUMBER,
|
'IntegerField': NUMBER,
|
||||||
'NullBooleanField': NUMBER,
|
|
||||||
'PositiveBigIntegerField': NUMBER,
|
'PositiveBigIntegerField': NUMBER,
|
||||||
'PositiveIntegerField': NUMBER,
|
'PositiveIntegerField': NUMBER,
|
||||||
'PositiveSmallIntegerField': NUMBER,
|
'PositiveSmallIntegerField': NUMBER,
|
||||||
|
|
|
@ -87,7 +87,6 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
||||||
'IPAddressField': 'inet',
|
'IPAddressField': 'inet',
|
||||||
'GenericIPAddressField': 'inet',
|
'GenericIPAddressField': 'inet',
|
||||||
'JSONField': 'jsonb',
|
'JSONField': 'jsonb',
|
||||||
'NullBooleanField': 'boolean',
|
|
||||||
'OneToOneField': 'integer',
|
'OneToOneField': 'integer',
|
||||||
'PositiveBigIntegerField': 'bigint',
|
'PositiveBigIntegerField': 'bigint',
|
||||||
'PositiveIntegerField': 'integer',
|
'PositiveIntegerField': 'integer',
|
||||||
|
|
|
@ -104,7 +104,6 @@ class DatabaseWrapper(BaseDatabaseWrapper):
|
||||||
'IPAddressField': 'char(15)',
|
'IPAddressField': 'char(15)',
|
||||||
'GenericIPAddressField': 'char(39)',
|
'GenericIPAddressField': 'char(39)',
|
||||||
'JSONField': 'text',
|
'JSONField': 'text',
|
||||||
'NullBooleanField': 'bool',
|
|
||||||
'OneToOneField': 'integer',
|
'OneToOneField': 'integer',
|
||||||
'PositiveBigIntegerField': 'bigint unsigned',
|
'PositiveBigIntegerField': 'bigint unsigned',
|
||||||
'PositiveIntegerField': 'integer unsigned',
|
'PositiveIntegerField': 'integer unsigned',
|
||||||
|
|
|
@ -277,7 +277,7 @@ class DatabaseOperations(BaseDatabaseOperations):
|
||||||
converters.append(self.get_decimalfield_converter(expression))
|
converters.append(self.get_decimalfield_converter(expression))
|
||||||
elif internal_type == 'UUIDField':
|
elif internal_type == 'UUIDField':
|
||||||
converters.append(self.convert_uuidfield_value)
|
converters.append(self.convert_uuidfield_value)
|
||||||
elif internal_type in ('NullBooleanField', 'BooleanField'):
|
elif internal_type == 'BooleanField':
|
||||||
converters.append(self.convert_booleanfield_value)
|
converters.append(self.convert_booleanfield_value)
|
||||||
return converters
|
return converters
|
||||||
|
|
||||||
|
|
|
@ -1987,13 +1987,13 @@ class NullBooleanField(BooleanField):
|
||||||
'invalid_nullable': _('“%(value)s” value must be either None, True or False.'),
|
'invalid_nullable': _('“%(value)s” value must be either None, True or False.'),
|
||||||
}
|
}
|
||||||
description = _("Boolean (Either True, False or None)")
|
description = _("Boolean (Either True, False or None)")
|
||||||
system_check_deprecated_details = {
|
system_check_removed_details = {
|
||||||
'msg': (
|
'msg': (
|
||||||
'NullBooleanField is deprecated. Support for it (except in '
|
'NullBooleanField is removed except for support in historical '
|
||||||
'historical migrations) will be removed in Django 4.0.'
|
'migrations.'
|
||||||
),
|
),
|
||||||
'hint': 'Use BooleanField(null=True) instead.',
|
'hint': 'Use BooleanField(null=True) instead.',
|
||||||
'id': 'fields.W903',
|
'id': 'fields.E903',
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
|
|
|
@ -206,7 +206,10 @@ Model fields
|
||||||
* **fields.W902**: ``FloatRangeField`` is deprecated and will be removed in
|
* **fields.W902**: ``FloatRangeField`` is deprecated and will be removed in
|
||||||
Django 3.1. *This check appeared in Django 2.2 and 3.0*.
|
Django 3.1. *This check appeared in Django 2.2 and 3.0*.
|
||||||
* **fields.W903**: ``NullBooleanField`` is deprecated. Support for it (except
|
* **fields.W903**: ``NullBooleanField`` is deprecated. Support for it (except
|
||||||
in historical migrations) will be removed in Django 4.0.
|
in historical migrations) will be removed in Django 4.0. *This check appeared
|
||||||
|
in Django 3.1 and 3.2*.
|
||||||
|
* **fields.E903**: ``NullBooleanField`` is removed except for support in
|
||||||
|
historical migrations.
|
||||||
* **fields.W904**: ``django.contrib.postgres.fields.JSONField`` is deprecated.
|
* **fields.W904**: ``django.contrib.postgres.fields.JSONField`` is deprecated.
|
||||||
Support for it (except in historical migrations) will be removed in Django
|
Support for it (except in historical migrations) will be removed in Django
|
||||||
4.0.
|
4.0.
|
||||||
|
|
|
@ -1254,17 +1254,6 @@ To query ``JSONField`` in the database, see :ref:`querying-jsonfield`.
|
||||||
objects and arrays (represented in Python using :py:class:`dict` and
|
objects and arrays (represented in Python using :py:class:`dict` and
|
||||||
:py:class:`list`) are supported.
|
:py:class:`list`) are supported.
|
||||||
|
|
||||||
``NullBooleanField``
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
.. class:: NullBooleanField(**options)
|
|
||||||
|
|
||||||
Like :class:`BooleanField` with ``null=True``.
|
|
||||||
|
|
||||||
.. deprecated:: 3.1
|
|
||||||
|
|
||||||
``NullBooleanField`` is deprecated in favor of ``BooleanField(null=True)``.
|
|
||||||
|
|
||||||
``PositiveBigIntegerField``
|
``PositiveBigIntegerField``
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
|
|
|
@ -189,8 +189,8 @@ Models
|
||||||
now support using field transforms.
|
now support using field transforms.
|
||||||
|
|
||||||
* :class:`~django.db.models.BooleanField` can now be ``null=True``. This is
|
* :class:`~django.db.models.BooleanField` can now be ``null=True``. This is
|
||||||
encouraged instead of :class:`~django.db.models.NullBooleanField`, which will
|
encouraged instead of ``NullBooleanField``, which will likely be deprecated
|
||||||
likely be deprecated in the future.
|
in the future.
|
||||||
|
|
||||||
* The new :meth:`.QuerySet.explain` method displays the database's execution
|
* The new :meth:`.QuerySet.explain` method displays the database's execution
|
||||||
plan of a queryset's query.
|
plan of a queryset's query.
|
||||||
|
|
|
@ -305,3 +305,6 @@ to remove usage of these features.
|
||||||
* The ``list`` message for ``ModelMultipleChoiceField`` is removed.
|
* The ``list`` message for ``ModelMultipleChoiceField`` is removed.
|
||||||
|
|
||||||
* Support for passing raw column aliases to ``QuerySet.order_by()`` is removed.
|
* Support for passing raw column aliases to ``QuerySet.order_by()`` is removed.
|
||||||
|
|
||||||
|
* The ``NullBooleanField`` model field is removed, except for support in
|
||||||
|
historical migrations.
|
||||||
|
|
|
@ -106,8 +106,6 @@ Model field Form field
|
||||||
:class:`ManyToManyField` :class:`~django.forms.ModelMultipleChoiceField`
|
:class:`ManyToManyField` :class:`~django.forms.ModelMultipleChoiceField`
|
||||||
(see below)
|
(see below)
|
||||||
|
|
||||||
:class:`NullBooleanField` :class:`~django.forms.NullBooleanField`
|
|
||||||
|
|
||||||
:class:`PositiveBigIntegerField` :class:`~django.forms.IntegerField`
|
:class:`PositiveBigIntegerField` :class:`~django.forms.IntegerField`
|
||||||
|
|
||||||
:class:`PositiveIntegerField` :class:`~django.forms.IntegerField`
|
:class:`PositiveIntegerField` :class:`~django.forms.IntegerField`
|
||||||
|
|
|
@ -29,7 +29,6 @@ class Book(models.Model):
|
||||||
blank=True, null=True,
|
blank=True, null=True,
|
||||||
)
|
)
|
||||||
is_best_seller = models.BooleanField(default=0, null=True)
|
is_best_seller = models.BooleanField(default=0, null=True)
|
||||||
is_best_seller2 = models.NullBooleanField(default=0)
|
|
||||||
date_registered = models.DateField(null=True)
|
date_registered = models.DateField(null=True)
|
||||||
availability = models.BooleanField(choices=(
|
availability = models.BooleanField(choices=(
|
||||||
(False, 'Paid'),
|
(False, 'Paid'),
|
||||||
|
|
|
@ -144,10 +144,6 @@ class BookAdmin(ModelAdmin):
|
||||||
ordering = ('-id',)
|
ordering = ('-id',)
|
||||||
|
|
||||||
|
|
||||||
class BookAdmin2(ModelAdmin):
|
|
||||||
list_filter = ('year', 'author', 'contributors', 'is_best_seller2', 'date_registered', 'no')
|
|
||||||
|
|
||||||
|
|
||||||
class BookAdminWithTupleBooleanFilter(BookAdmin):
|
class BookAdminWithTupleBooleanFilter(BookAdmin):
|
||||||
list_filter = (
|
list_filter = (
|
||||||
'year',
|
'year',
|
||||||
|
@ -289,22 +285,22 @@ class ListFiltersTests(TestCase):
|
||||||
cls.djangonaut_book = Book.objects.create(
|
cls.djangonaut_book = Book.objects.create(
|
||||||
title='Djangonaut: an art of living', year=2009,
|
title='Djangonaut: an art of living', year=2009,
|
||||||
author=cls.alfred, is_best_seller=True, date_registered=cls.today,
|
author=cls.alfred, is_best_seller=True, date_registered=cls.today,
|
||||||
is_best_seller2=True, availability=True,
|
availability=True,
|
||||||
)
|
)
|
||||||
cls.bio_book = Book.objects.create(
|
cls.bio_book = Book.objects.create(
|
||||||
title='Django: a biography', year=1999, author=cls.alfred,
|
title='Django: a biography', year=1999, author=cls.alfred,
|
||||||
is_best_seller=False, no=207,
|
is_best_seller=False, no=207,
|
||||||
is_best_seller2=False, availability=False,
|
availability=False,
|
||||||
)
|
)
|
||||||
cls.django_book = Book.objects.create(
|
cls.django_book = Book.objects.create(
|
||||||
title='The Django Book', year=None, author=cls.bob,
|
title='The Django Book', year=None, author=cls.bob,
|
||||||
is_best_seller=None, date_registered=cls.today, no=103,
|
is_best_seller=None, date_registered=cls.today, no=103,
|
||||||
is_best_seller2=None, availability=True,
|
availability=True,
|
||||||
)
|
)
|
||||||
cls.guitar_book = Book.objects.create(
|
cls.guitar_book = Book.objects.create(
|
||||||
title='Guitar for dummies', year=2002, is_best_seller=True,
|
title='Guitar for dummies', year=2002, is_best_seller=True,
|
||||||
date_registered=cls.one_week_ago,
|
date_registered=cls.one_week_ago,
|
||||||
is_best_seller2=True, availability=None,
|
availability=None,
|
||||||
)
|
)
|
||||||
cls.guitar_book.contributors.set([cls.bob, cls.lisa])
|
cls.guitar_book.contributors.set([cls.bob, cls.lisa])
|
||||||
|
|
||||||
|
@ -1014,58 +1010,6 @@ class ListFiltersTests(TestCase):
|
||||||
self.assertIs(choice['selected'], True)
|
self.assertIs(choice['selected'], True)
|
||||||
self.assertEqual(choice['query_string'], '?')
|
self.assertEqual(choice['query_string'], '?')
|
||||||
|
|
||||||
def test_booleanfieldlistfilter_nullbooleanfield(self):
|
|
||||||
modeladmin = BookAdmin2(Book, site)
|
|
||||||
|
|
||||||
request = self.request_factory.get('/')
|
|
||||||
request.user = self.alfred
|
|
||||||
changelist = modeladmin.get_changelist_instance(request)
|
|
||||||
|
|
||||||
request = self.request_factory.get('/', {'is_best_seller2__exact': 0})
|
|
||||||
request.user = self.alfred
|
|
||||||
changelist = modeladmin.get_changelist_instance(request)
|
|
||||||
|
|
||||||
# Make sure the correct queryset is returned
|
|
||||||
queryset = changelist.get_queryset(request)
|
|
||||||
self.assertEqual(list(queryset), [self.bio_book])
|
|
||||||
|
|
||||||
# Make sure the correct choice is selected
|
|
||||||
filterspec = changelist.get_filters(request)[0][3]
|
|
||||||
self.assertEqual(filterspec.title, 'is best seller2')
|
|
||||||
choice = select_by(filterspec.choices(changelist), "display", "No")
|
|
||||||
self.assertIs(choice['selected'], True)
|
|
||||||
self.assertEqual(choice['query_string'], '?is_best_seller2__exact=0')
|
|
||||||
|
|
||||||
request = self.request_factory.get('/', {'is_best_seller2__exact': 1})
|
|
||||||
request.user = self.alfred
|
|
||||||
changelist = modeladmin.get_changelist_instance(request)
|
|
||||||
|
|
||||||
# Make sure the correct queryset is returned
|
|
||||||
queryset = changelist.get_queryset(request)
|
|
||||||
self.assertEqual(list(queryset), [self.guitar_book, self.djangonaut_book])
|
|
||||||
|
|
||||||
# Make sure the correct choice is selected
|
|
||||||
filterspec = changelist.get_filters(request)[0][3]
|
|
||||||
self.assertEqual(filterspec.title, 'is best seller2')
|
|
||||||
choice = select_by(filterspec.choices(changelist), "display", "Yes")
|
|
||||||
self.assertIs(choice['selected'], True)
|
|
||||||
self.assertEqual(choice['query_string'], '?is_best_seller2__exact=1')
|
|
||||||
|
|
||||||
request = self.request_factory.get('/', {'is_best_seller2__isnull': 'True'})
|
|
||||||
request.user = self.alfred
|
|
||||||
changelist = modeladmin.get_changelist_instance(request)
|
|
||||||
|
|
||||||
# Make sure the correct queryset is returned
|
|
||||||
queryset = changelist.get_queryset(request)
|
|
||||||
self.assertEqual(list(queryset), [self.django_book])
|
|
||||||
|
|
||||||
# Make sure the correct choice is selected
|
|
||||||
filterspec = changelist.get_filters(request)[0][3]
|
|
||||||
self.assertEqual(filterspec.title, 'is best seller2')
|
|
||||||
choice = select_by(filterspec.choices(changelist), "display", "Unknown")
|
|
||||||
self.assertIs(choice['selected'], True)
|
|
||||||
self.assertEqual(choice['query_string'], '?is_best_seller2__isnull=True')
|
|
||||||
|
|
||||||
def test_fieldlistfilter_underscorelookup_tuple(self):
|
def test_fieldlistfilter_underscorelookup_tuple(self):
|
||||||
"""
|
"""
|
||||||
Ensure ('fieldpath', ClassName ) lookups pass lookup_allowed checks
|
Ensure ('fieldpath', ClassName ) lookups pass lookup_allowed checks
|
||||||
|
|
|
@ -163,12 +163,6 @@ class UtilsTests(SimpleTestCase):
|
||||||
display_value = display_for_field(None, models.TimeField(), self.empty_value)
|
display_value = display_for_field(None, models.TimeField(), self.empty_value)
|
||||||
self.assertEqual(display_value, self.empty_value)
|
self.assertEqual(display_value, self.empty_value)
|
||||||
|
|
||||||
# Regression test for #13071: NullBooleanField has special
|
|
||||||
# handling.
|
|
||||||
display_value = display_for_field(None, models.NullBooleanField(), self.empty_value)
|
|
||||||
expected = '<img src="%sadmin/img/icon-unknown.svg" alt="None">' % settings.STATIC_URL
|
|
||||||
self.assertHTMLEqual(display_value, expected)
|
|
||||||
|
|
||||||
display_value = display_for_field(None, models.BooleanField(null=True), self.empty_value)
|
display_value = display_for_field(None, models.BooleanField(null=True), self.empty_value)
|
||||||
expected = '<img src="%sadmin/img/icon-unknown.svg" alt="None" />' % settings.STATIC_URL
|
expected = '<img src="%sadmin/img/icon-unknown.svg" alt="None" />' % settings.STATIC_URL
|
||||||
self.assertHTMLEqual(display_value, expected)
|
self.assertHTMLEqual(display_value, expected)
|
||||||
|
|
|
@ -4,8 +4,8 @@ from decimal import Decimal
|
||||||
from django.core.exceptions import FieldDoesNotExist, FieldError
|
from django.core.exceptions import FieldDoesNotExist, FieldError
|
||||||
from django.db.models import (
|
from django.db.models import (
|
||||||
BooleanField, Case, CharField, Count, DateTimeField, DecimalField, Exists,
|
BooleanField, Case, CharField, Count, DateTimeField, DecimalField, Exists,
|
||||||
ExpressionWrapper, F, FloatField, Func, IntegerField, Max,
|
ExpressionWrapper, F, FloatField, Func, IntegerField, Max, OuterRef, Q,
|
||||||
NullBooleanField, OuterRef, Q, Subquery, Sum, Value, When,
|
Subquery, Sum, Value, When,
|
||||||
)
|
)
|
||||||
from django.db.models.expressions import RawSQL
|
from django.db.models.expressions import RawSQL
|
||||||
from django.db.models.functions import (
|
from django.db.models.functions import (
|
||||||
|
@ -641,14 +641,12 @@ class NonAggregateAnnotationTestCase(TestCase):
|
||||||
is_book=Value(True, output_field=BooleanField()),
|
is_book=Value(True, output_field=BooleanField()),
|
||||||
is_pony=Value(False, output_field=BooleanField()),
|
is_pony=Value(False, output_field=BooleanField()),
|
||||||
is_none=Value(None, output_field=BooleanField(null=True)),
|
is_none=Value(None, output_field=BooleanField(null=True)),
|
||||||
is_none_old=Value(None, output_field=NullBooleanField()),
|
|
||||||
)
|
)
|
||||||
self.assertGreater(len(books), 0)
|
self.assertGreater(len(books), 0)
|
||||||
for book in books:
|
for book in books:
|
||||||
self.assertIs(book.is_book, True)
|
self.assertIs(book.is_book, True)
|
||||||
self.assertIs(book.is_pony, False)
|
self.assertIs(book.is_pony, False)
|
||||||
self.assertIsNone(book.is_none)
|
self.assertIsNone(book.is_none)
|
||||||
self.assertIsNone(book.is_none_old)
|
|
||||||
|
|
||||||
def test_annotation_in_f_grouped_by_annotation(self):
|
def test_annotation_in_f_grouped_by_annotation(self):
|
||||||
qs = (
|
qs = (
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
from django.db import DatabaseError, connection
|
from django.db import DatabaseError, connection
|
||||||
from django.db.models import BooleanField, NullBooleanField
|
from django.db.models import BooleanField
|
||||||
from django.test import TransactionTestCase
|
from django.test import TransactionTestCase
|
||||||
|
|
||||||
from ..models import Square
|
from ..models import Square
|
||||||
|
@ -48,7 +48,7 @@ class Tests(unittest.TestCase):
|
||||||
|
|
||||||
def test_boolean_constraints(self):
|
def test_boolean_constraints(self):
|
||||||
"""Boolean fields have check constraints on their values."""
|
"""Boolean fields have check constraints on their values."""
|
||||||
for field in (BooleanField(), NullBooleanField(), BooleanField(null=True)):
|
for field in (BooleanField(), BooleanField(null=True)):
|
||||||
with self.subTest(field=field):
|
with self.subTest(field=field):
|
||||||
field.set_attributes_from_name('is_nice')
|
field.set_attributes_from_name('is_nice')
|
||||||
self.assertIn('"IS_NICE" IN (0,1)', field.db_check(connection))
|
self.assertIn('"IS_NICE" IN (0,1)', field.db_check(connection))
|
||||||
|
|
|
@ -83,7 +83,6 @@ class NullableFields(models.Model):
|
||||||
float_field = models.FloatField(null=True, default=3.2)
|
float_field = models.FloatField(null=True, default=3.2)
|
||||||
integer_field = models.IntegerField(null=True, default=2)
|
integer_field = models.IntegerField(null=True, default=2)
|
||||||
null_boolean_field = models.BooleanField(null=True, default=False)
|
null_boolean_field = models.BooleanField(null=True, default=False)
|
||||||
null_boolean_field_old = models.NullBooleanField(null=True, default=False)
|
|
||||||
positive_big_integer_field = models.PositiveBigIntegerField(null=True, default=2 ** 63 - 1)
|
positive_big_integer_field = models.PositiveBigIntegerField(null=True, default=2 ** 63 - 1)
|
||||||
positive_integer_field = models.PositiveIntegerField(null=True, default=3)
|
positive_integer_field = models.PositiveIntegerField(null=True, default=3)
|
||||||
positive_small_integer_field = models.PositiveSmallIntegerField(null=True, default=4)
|
positive_small_integer_field = models.PositiveSmallIntegerField(null=True, default=4)
|
||||||
|
|
|
@ -10,7 +10,6 @@ class Donut(models.Model):
|
||||||
name = models.CharField(max_length=100)
|
name = models.CharField(max_length=100)
|
||||||
is_frosted = models.BooleanField(default=False)
|
is_frosted = models.BooleanField(default=False)
|
||||||
has_sprinkles = models.BooleanField(null=True)
|
has_sprinkles = models.BooleanField(null=True)
|
||||||
has_sprinkles_old = models.NullBooleanField()
|
|
||||||
baked_date = models.DateField(null=True)
|
baked_date = models.DateField(null=True)
|
||||||
baked_time = models.TimeField(null=True)
|
baked_time = models.TimeField(null=True)
|
||||||
consumed_at = models.DateTimeField(null=True)
|
consumed_at = models.DateTimeField(null=True)
|
||||||
|
|
|
@ -12,18 +12,14 @@ class DataTypesTestCase(TestCase):
|
||||||
d = Donut(name='Apple Fritter')
|
d = Donut(name='Apple Fritter')
|
||||||
self.assertFalse(d.is_frosted)
|
self.assertFalse(d.is_frosted)
|
||||||
self.assertIsNone(d.has_sprinkles)
|
self.assertIsNone(d.has_sprinkles)
|
||||||
self.assertIsNone(d.has_sprinkles_old)
|
|
||||||
d.has_sprinkles = True
|
d.has_sprinkles = True
|
||||||
d.has_sprinkles_old = True
|
|
||||||
self.assertTrue(d.has_sprinkles)
|
self.assertTrue(d.has_sprinkles)
|
||||||
self.assertTrue(d.has_sprinkles_old)
|
|
||||||
|
|
||||||
d.save()
|
d.save()
|
||||||
|
|
||||||
d2 = Donut.objects.get(name='Apple Fritter')
|
d2 = Donut.objects.get(name='Apple Fritter')
|
||||||
self.assertFalse(d2.is_frosted)
|
self.assertFalse(d2.is_frosted)
|
||||||
self.assertTrue(d2.has_sprinkles)
|
self.assertTrue(d2.has_sprinkles)
|
||||||
self.assertTrue(d2.has_sprinkles_old)
|
|
||||||
|
|
||||||
def test_date_type(self):
|
def test_date_type(self):
|
||||||
d = Donut(name='Apple Fritter')
|
d = Donut(name='Apple Fritter')
|
||||||
|
|
|
@ -26,7 +26,6 @@ class CaseTestModel(models.Model):
|
||||||
image = models.ImageField(null=True)
|
image = models.ImageField(null=True)
|
||||||
generic_ip_address = models.GenericIPAddressField(null=True)
|
generic_ip_address = models.GenericIPAddressField(null=True)
|
||||||
null_boolean = models.BooleanField(null=True)
|
null_boolean = models.BooleanField(null=True)
|
||||||
null_boolean_old = models.NullBooleanField()
|
|
||||||
positive_integer = models.PositiveIntegerField(null=True)
|
positive_integer = models.PositiveIntegerField(null=True)
|
||||||
positive_small_integer = models.PositiveSmallIntegerField(null=True)
|
positive_small_integer = models.PositiveSmallIntegerField(null=True)
|
||||||
positive_big_integer = models.PositiveSmallIntegerField(null=True)
|
positive_big_integer = models.PositiveSmallIntegerField(null=True)
|
||||||
|
|
|
@ -805,19 +805,6 @@ class CaseExpressionTests(TestCase):
|
||||||
transform=attrgetter('integer', 'null_boolean')
|
transform=attrgetter('integer', 'null_boolean')
|
||||||
)
|
)
|
||||||
|
|
||||||
def test_update_null_boolean_old(self):
|
|
||||||
CaseTestModel.objects.update(
|
|
||||||
null_boolean_old=Case(
|
|
||||||
When(integer=1, then=True),
|
|
||||||
When(integer=2, then=False),
|
|
||||||
),
|
|
||||||
)
|
|
||||||
self.assertQuerysetEqual(
|
|
||||||
CaseTestModel.objects.all().order_by('pk'),
|
|
||||||
[(1, True), (2, False), (3, None), (2, False), (3, None), (3, None), (4, None)],
|
|
||||||
transform=attrgetter('integer', 'null_boolean_old')
|
|
||||||
)
|
|
||||||
|
|
||||||
def test_update_positive_big_integer(self):
|
def test_update_positive_big_integer(self):
|
||||||
CaseTestModel.objects.update(
|
CaseTestModel.objects.update(
|
||||||
positive_big_integer=Case(
|
positive_big_integer=Case(
|
||||||
|
|
|
@ -432,13 +432,6 @@ class FieldDeconstructionTests(SimpleTestCase):
|
||||||
self.assertEqual(kwargs, {"to": "auth.Permission"})
|
self.assertEqual(kwargs, {"to": "auth.Permission"})
|
||||||
self.assertEqual(kwargs['to'].setting_name, "AUTH_USER_MODEL")
|
self.assertEqual(kwargs['to'].setting_name, "AUTH_USER_MODEL")
|
||||||
|
|
||||||
def test_null_boolean_field(self):
|
|
||||||
field = models.NullBooleanField()
|
|
||||||
name, path, args, kwargs = field.deconstruct()
|
|
||||||
self.assertEqual(path, "django.db.models.NullBooleanField")
|
|
||||||
self.assertEqual(args, [])
|
|
||||||
self.assertEqual(kwargs, {})
|
|
||||||
|
|
||||||
def test_positive_integer_field(self):
|
def test_positive_integer_field(self):
|
||||||
field = models.PositiveIntegerField()
|
field = models.PositiveIntegerField()
|
||||||
name, path, args, kwargs = field.deconstruct()
|
name, path, args, kwargs = field.deconstruct()
|
||||||
|
|
|
@ -44,11 +44,11 @@ class DeprecatedFieldsTests(SimpleTestCase):
|
||||||
|
|
||||||
model = NullBooleanFieldModel()
|
model = NullBooleanFieldModel()
|
||||||
self.assertEqual(model.check(), [
|
self.assertEqual(model.check(), [
|
||||||
checks.Warning(
|
checks.Error(
|
||||||
'NullBooleanField is deprecated. Support for it (except in '
|
'NullBooleanField is removed except for support in historical '
|
||||||
'historical migrations) will be removed in Django 4.0.',
|
'migrations.',
|
||||||
hint='Use BooleanField(null=True) instead.',
|
hint='Use BooleanField(null=True) instead.',
|
||||||
obj=NullBooleanFieldModel._meta.get_field('nb'),
|
obj=NullBooleanFieldModel._meta.get_field('nb'),
|
||||||
id='fields.W903',
|
id='fields.E903',
|
||||||
),
|
),
|
||||||
])
|
])
|
||||||
|
|
|
@ -135,7 +135,6 @@ class Post(models.Model):
|
||||||
|
|
||||||
class NullBooleanModel(models.Model):
|
class NullBooleanModel(models.Model):
|
||||||
nbfield = models.BooleanField(null=True, blank=True)
|
nbfield = models.BooleanField(null=True, blank=True)
|
||||||
nbfield_old = models.NullBooleanField()
|
|
||||||
|
|
||||||
|
|
||||||
class BooleanModel(models.Model):
|
class BooleanModel(models.Model):
|
||||||
|
@ -192,16 +191,15 @@ class VerboseNameField(models.Model):
|
||||||
# field_image = models.ImageField("verbose field")
|
# field_image = models.ImageField("verbose field")
|
||||||
field11 = models.IntegerField("verbose field11")
|
field11 = models.IntegerField("verbose field11")
|
||||||
field12 = models.GenericIPAddressField("verbose field12", protocol="ipv4")
|
field12 = models.GenericIPAddressField("verbose field12", protocol="ipv4")
|
||||||
field13 = models.NullBooleanField("verbose field13")
|
field13 = models.PositiveIntegerField("verbose field13")
|
||||||
field14 = models.PositiveIntegerField("verbose field14")
|
field14 = models.PositiveSmallIntegerField("verbose field14")
|
||||||
field15 = models.PositiveSmallIntegerField("verbose field15")
|
field15 = models.SlugField("verbose field15")
|
||||||
field16 = models.SlugField("verbose field16")
|
field16 = models.SmallIntegerField("verbose field16")
|
||||||
field17 = models.SmallIntegerField("verbose field17")
|
field17 = models.TextField("verbose field17")
|
||||||
field18 = models.TextField("verbose field18")
|
field18 = models.TimeField("verbose field18")
|
||||||
field19 = models.TimeField("verbose field19")
|
field19 = models.URLField("verbose field19")
|
||||||
field20 = models.URLField("verbose field20")
|
field20 = models.UUIDField("verbose field20")
|
||||||
field21 = models.UUIDField("verbose field21")
|
field21 = models.DurationField("verbose field21")
|
||||||
field22 = models.DurationField("verbose field22")
|
|
||||||
|
|
||||||
|
|
||||||
class GenericIPAddress(models.Model):
|
class GenericIPAddress(models.Model):
|
||||||
|
@ -385,7 +383,6 @@ class AllFieldsModel(models.Model):
|
||||||
floatf = models.FloatField()
|
floatf = models.FloatField()
|
||||||
integer = models.IntegerField()
|
integer = models.IntegerField()
|
||||||
generic_ip = models.GenericIPAddressField()
|
generic_ip = models.GenericIPAddressField()
|
||||||
null_boolean = models.NullBooleanField()
|
|
||||||
positive_integer = models.PositiveIntegerField()
|
positive_integer = models.PositiveIntegerField()
|
||||||
positive_small_integer = models.PositiveSmallIntegerField()
|
positive_small_integer = models.PositiveSmallIntegerField()
|
||||||
slug = models.SlugField()
|
slug = models.SlugField()
|
||||||
|
|
|
@ -26,18 +26,12 @@ class BooleanFieldTests(TestCase):
|
||||||
def test_nullbooleanfield_get_prep_value(self):
|
def test_nullbooleanfield_get_prep_value(self):
|
||||||
self._test_get_prep_value(models.BooleanField(null=True))
|
self._test_get_prep_value(models.BooleanField(null=True))
|
||||||
|
|
||||||
def test_nullbooleanfield_old_get_prep_value(self):
|
|
||||||
self._test_get_prep_value(models.NullBooleanField())
|
|
||||||
|
|
||||||
def test_booleanfield_to_python(self):
|
def test_booleanfield_to_python(self):
|
||||||
self._test_to_python(models.BooleanField())
|
self._test_to_python(models.BooleanField())
|
||||||
|
|
||||||
def test_nullbooleanfield_to_python(self):
|
def test_nullbooleanfield_to_python(self):
|
||||||
self._test_to_python(models.BooleanField(null=True))
|
self._test_to_python(models.BooleanField(null=True))
|
||||||
|
|
||||||
def test_nullbooleanfield_old_to_python(self):
|
|
||||||
self._test_to_python(models.NullBooleanField())
|
|
||||||
|
|
||||||
def test_booleanfield_choices_blank(self):
|
def test_booleanfield_choices_blank(self):
|
||||||
"""
|
"""
|
||||||
BooleanField with choices and defaults doesn't generate a formfield
|
BooleanField with choices and defaults doesn't generate a formfield
|
||||||
|
@ -59,8 +53,6 @@ class BooleanFieldTests(TestCase):
|
||||||
def test_nullbooleanfield_formfield(self):
|
def test_nullbooleanfield_formfield(self):
|
||||||
f = models.BooleanField(null=True)
|
f = models.BooleanField(null=True)
|
||||||
self.assertIsInstance(f.formfield(), forms.NullBooleanField)
|
self.assertIsInstance(f.formfield(), forms.NullBooleanField)
|
||||||
f = models.NullBooleanField()
|
|
||||||
self.assertIsInstance(f.formfield(), forms.NullBooleanField)
|
|
||||||
|
|
||||||
def test_return_type(self):
|
def test_return_type(self):
|
||||||
b = BooleanModel.objects.create(bfield=True)
|
b = BooleanModel.objects.create(bfield=True)
|
||||||
|
@ -71,15 +63,13 @@ class BooleanFieldTests(TestCase):
|
||||||
b2.refresh_from_db()
|
b2.refresh_from_db()
|
||||||
self.assertIs(b2.bfield, False)
|
self.assertIs(b2.bfield, False)
|
||||||
|
|
||||||
b3 = NullBooleanModel.objects.create(nbfield=True, nbfield_old=True)
|
b3 = NullBooleanModel.objects.create(nbfield=True)
|
||||||
b3.refresh_from_db()
|
b3.refresh_from_db()
|
||||||
self.assertIs(b3.nbfield, True)
|
self.assertIs(b3.nbfield, True)
|
||||||
self.assertIs(b3.nbfield_old, True)
|
|
||||||
|
|
||||||
b4 = NullBooleanModel.objects.create(nbfield=False, nbfield_old=False)
|
b4 = NullBooleanModel.objects.create(nbfield=False)
|
||||||
b4.refresh_from_db()
|
b4.refresh_from_db()
|
||||||
self.assertIs(b4.nbfield, False)
|
self.assertIs(b4.nbfield, False)
|
||||||
self.assertIs(b4.nbfield_old, False)
|
|
||||||
|
|
||||||
# When an extra clause exists, the boolean conversions are applied with
|
# When an extra clause exists, the boolean conversions are applied with
|
||||||
# an offset (#13293).
|
# an offset (#13293).
|
||||||
|
@ -92,8 +82,8 @@ class BooleanFieldTests(TestCase):
|
||||||
"""
|
"""
|
||||||
bmt = BooleanModel.objects.create(bfield=True)
|
bmt = BooleanModel.objects.create(bfield=True)
|
||||||
bmf = BooleanModel.objects.create(bfield=False)
|
bmf = BooleanModel.objects.create(bfield=False)
|
||||||
nbmt = NullBooleanModel.objects.create(nbfield=True, nbfield_old=True)
|
nbmt = NullBooleanModel.objects.create(nbfield=True)
|
||||||
nbmf = NullBooleanModel.objects.create(nbfield=False, nbfield_old=False)
|
nbmf = NullBooleanModel.objects.create(nbfield=False)
|
||||||
m1 = FksToBooleans.objects.create(bf=bmt, nbf=nbmt)
|
m1 = FksToBooleans.objects.create(bf=bmt, nbf=nbmt)
|
||||||
m2 = FksToBooleans.objects.create(bf=bmf, nbf=nbmf)
|
m2 = FksToBooleans.objects.create(bf=bmf, nbf=nbmf)
|
||||||
|
|
||||||
|
@ -107,10 +97,8 @@ class BooleanFieldTests(TestCase):
|
||||||
mc = FksToBooleans.objects.select_related().get(pk=m2.id)
|
mc = FksToBooleans.objects.select_related().get(pk=m2.id)
|
||||||
self.assertIs(mb.bf.bfield, True)
|
self.assertIs(mb.bf.bfield, True)
|
||||||
self.assertIs(mb.nbf.nbfield, True)
|
self.assertIs(mb.nbf.nbfield, True)
|
||||||
self.assertIs(mb.nbf.nbfield_old, True)
|
|
||||||
self.assertIs(mc.bf.bfield, False)
|
self.assertIs(mc.bf.bfield, False)
|
||||||
self.assertIs(mc.nbf.nbfield, False)
|
self.assertIs(mc.nbf.nbfield, False)
|
||||||
self.assertIs(mc.nbf.nbfield_old, False)
|
|
||||||
|
|
||||||
def test_null_default(self):
|
def test_null_default(self):
|
||||||
"""
|
"""
|
||||||
|
@ -126,7 +114,6 @@ class BooleanFieldTests(TestCase):
|
||||||
|
|
||||||
nb = NullBooleanModel()
|
nb = NullBooleanModel()
|
||||||
self.assertIsNone(nb.nbfield)
|
self.assertIsNone(nb.nbfield)
|
||||||
self.assertIsNone(nb.nbfield_old)
|
|
||||||
nb.save() # no error
|
nb.save() # no error
|
||||||
|
|
||||||
|
|
||||||
|
@ -142,5 +129,5 @@ class ValidationTest(SimpleTestCase):
|
||||||
NullBooleanField shouldn't throw a validation error when given a value
|
NullBooleanField shouldn't throw a validation error when given a value
|
||||||
of None.
|
of None.
|
||||||
"""
|
"""
|
||||||
nullboolean = NullBooleanModel(nbfield=None, nbfield_old=None)
|
nullboolean = NullBooleanModel(nbfield=None)
|
||||||
nullboolean.full_clean()
|
nullboolean.full_clean()
|
||||||
|
|
|
@ -5,9 +5,8 @@ from django.db.models import (
|
||||||
AutoField, BinaryField, BooleanField, CharField, DateField, DateTimeField,
|
AutoField, BinaryField, BooleanField, CharField, DateField, DateTimeField,
|
||||||
DecimalField, EmailField, FileField, FilePathField, FloatField,
|
DecimalField, EmailField, FileField, FilePathField, FloatField,
|
||||||
GenericIPAddressField, ImageField, IntegerField, IPAddressField,
|
GenericIPAddressField, ImageField, IntegerField, IPAddressField,
|
||||||
NullBooleanField, PositiveBigIntegerField, PositiveIntegerField,
|
PositiveBigIntegerField, PositiveIntegerField, PositiveSmallIntegerField,
|
||||||
PositiveSmallIntegerField, SlugField, SmallIntegerField, TextField,
|
SlugField, SmallIntegerField, TextField, TimeField, URLField,
|
||||||
TimeField, URLField,
|
|
||||||
)
|
)
|
||||||
from django.test import SimpleTestCase
|
from django.test import SimpleTestCase
|
||||||
from django.utils.functional import lazy
|
from django.utils.functional import lazy
|
||||||
|
@ -85,10 +84,6 @@ class PromiseTest(SimpleTestCase):
|
||||||
lazy_func = lazy(lambda: 0, int)
|
lazy_func = lazy(lambda: 0, int)
|
||||||
self.assertIsInstance(GenericIPAddressField().get_prep_value(lazy_func()), str)
|
self.assertIsInstance(GenericIPAddressField().get_prep_value(lazy_func()), str)
|
||||||
|
|
||||||
def test_NullBooleanField(self):
|
|
||||||
lazy_func = lazy(lambda: True, bool)
|
|
||||||
self.assertIsInstance(NullBooleanField().get_prep_value(lazy_func()), bool)
|
|
||||||
|
|
||||||
def test_PositiveIntegerField(self):
|
def test_PositiveIntegerField(self):
|
||||||
lazy_func = lazy(lambda: 1, int)
|
lazy_func = lazy(lambda: 1, int)
|
||||||
self.assertIsInstance(PositiveIntegerField().get_prep_value(lazy_func()), int)
|
self.assertIsInstance(PositiveIntegerField().get_prep_value(lazy_func()), int)
|
||||||
|
|
|
@ -56,7 +56,7 @@ class BasicFieldTests(SimpleTestCase):
|
||||||
|
|
||||||
def test_field_verbose_name(self):
|
def test_field_verbose_name(self):
|
||||||
m = VerboseNameField
|
m = VerboseNameField
|
||||||
for i in range(1, 23):
|
for i in range(1, 22):
|
||||||
self.assertEqual(m._meta.get_field('field%d' % i).verbose_name, 'verbose field%d' % i)
|
self.assertEqual(m._meta.get_field('field%d' % i).verbose_name, 'verbose field%d' % i)
|
||||||
|
|
||||||
self.assertEqual(m._meta.get_field('id').verbose_name, 'verbose pk')
|
self.assertEqual(m._meta.get_field('id').verbose_name, 'verbose pk')
|
||||||
|
|
|
@ -191,7 +191,6 @@ def setup(verbosity, test_labels, parallel, start_at, start_after):
|
||||||
settings.LOGGING = log_config
|
settings.LOGGING = log_config
|
||||||
settings.SILENCED_SYSTEM_CHECKS = [
|
settings.SILENCED_SYSTEM_CHECKS = [
|
||||||
'fields.W342', # ForeignKey(unique=True) -> OneToOneField
|
'fields.W342', # ForeignKey(unique=True) -> OneToOneField
|
||||||
'fields.W903', # NullBooleanField deprecated.
|
|
||||||
]
|
]
|
||||||
|
|
||||||
# Load all the ALWAYS_INSTALLED_APPS.
|
# Load all the ALWAYS_INSTALLED_APPS.
|
||||||
|
|
|
@ -70,10 +70,6 @@ class GenericIPAddressData(models.Model):
|
||||||
data = models.GenericIPAddressField(null=True)
|
data = models.GenericIPAddressField(null=True)
|
||||||
|
|
||||||
|
|
||||||
class NullBooleanData(models.Model):
|
|
||||||
data = models.NullBooleanField(null=True)
|
|
||||||
|
|
||||||
|
|
||||||
class PositiveBigIntegerData(models.Model):
|
class PositiveBigIntegerData(models.Model):
|
||||||
data = models.PositiveBigIntegerField(null=True)
|
data = models.PositiveBigIntegerField(null=True)
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,8 @@ from .models import (
|
||||||
GenericData, GenericIPAddressData, GenericIPAddressPKData,
|
GenericData, GenericIPAddressData, GenericIPAddressPKData,
|
||||||
InheritAbstractModel, InheritBaseModel, IntegerData, IntegerPKData,
|
InheritAbstractModel, InheritBaseModel, IntegerData, IntegerPKData,
|
||||||
Intermediate, LengthModel, M2MData, M2MIntermediateData, M2MSelfData,
|
Intermediate, LengthModel, M2MData, M2MIntermediateData, M2MSelfData,
|
||||||
ModifyingSaveData, NullBooleanData, O2OData, PositiveBigIntegerData,
|
ModifyingSaveData, O2OData, PositiveBigIntegerData, PositiveIntegerData,
|
||||||
PositiveIntegerData, PositiveIntegerPKData, PositiveSmallIntegerData,
|
PositiveIntegerPKData, PositiveSmallIntegerData,
|
||||||
PositiveSmallIntegerPKData, SlugData, SlugPKData, SmallData, SmallPKData,
|
PositiveSmallIntegerPKData, SlugData, SlugPKData, SmallData, SmallPKData,
|
||||||
Tag, TextData, TimeData, UniqueAnchor, UUIDData, UUIDDefaultData,
|
Tag, TextData, TimeData, UniqueAnchor, UUIDData, UUIDDefaultData,
|
||||||
)
|
)
|
||||||
|
@ -238,9 +238,6 @@ test_data = [
|
||||||
# (XX, ImageData
|
# (XX, ImageData
|
||||||
(data_obj, 95, GenericIPAddressData, "fe80:1424:2223:6cff:fe8a:2e8a:2151:abcd"),
|
(data_obj, 95, GenericIPAddressData, "fe80:1424:2223:6cff:fe8a:2e8a:2151:abcd"),
|
||||||
(data_obj, 96, GenericIPAddressData, None),
|
(data_obj, 96, GenericIPAddressData, None),
|
||||||
(data_obj, 100, NullBooleanData, True),
|
|
||||||
(data_obj, 101, NullBooleanData, False),
|
|
||||||
(data_obj, 102, NullBooleanData, None),
|
|
||||||
(data_obj, 110, PositiveBigIntegerData, 9223372036854775807),
|
(data_obj, 110, PositiveBigIntegerData, 9223372036854775807),
|
||||||
(data_obj, 111, PositiveBigIntegerData, None),
|
(data_obj, 111, PositiveBigIntegerData, None),
|
||||||
(data_obj, 120, PositiveIntegerData, 123456789),
|
(data_obj, 120, PositiveIntegerData, 123456789),
|
||||||
|
|
|
@ -36,8 +36,8 @@ class ValidationMessagesTest(TestCase):
|
||||||
self._test_validation_messages(f, 'fõo', ['“fõo” value must be a decimal number.'])
|
self._test_validation_messages(f, 'fõo', ['“fõo” value must be a decimal number.'])
|
||||||
|
|
||||||
def test_null_boolean_field_raises_error_message(self):
|
def test_null_boolean_field_raises_error_message(self):
|
||||||
f = models.NullBooleanField()
|
f = models.BooleanField(null=True)
|
||||||
self._test_validation_messages(f, 'fõo', ['“fõo” value must be either None, True or False.'])
|
self._test_validation_messages(f, 'fõo', ['“fõo” value must be either True, False, or None.'])
|
||||||
|
|
||||||
def test_date_field_raises_error_message(self):
|
def test_date_field_raises_error_message(self):
|
||||||
f = models.DateField()
|
f = models.DateField()
|
||||||
|
|
Loading…
Reference in New Issue