Fixed #18407 -- Made model field's to_python methods fully accept unicode.
When generating error message in to_python, any unicode string containing non-ascii characters triggered a UnicodeEncodeError for most field types.
This commit is contained in:
parent
473c272246
commit
0dc904979d
|
@ -17,7 +17,7 @@ from django.utils.functional import curry, total_ordering
|
||||||
from django.utils.text import capfirst
|
from django.utils.text import capfirst
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
from django.utils.translation import ugettext_lazy as _
|
from django.utils.translation import ugettext_lazy as _
|
||||||
from django.utils.encoding import smart_unicode, force_unicode, smart_str
|
from django.utils.encoding import smart_unicode, force_unicode
|
||||||
from django.utils.ipv6 import clean_ipv6_address
|
from django.utils.ipv6 import clean_ipv6_address
|
||||||
|
|
||||||
class NOT_PROVIDED:
|
class NOT_PROVIDED:
|
||||||
|
@ -530,7 +530,7 @@ class AutoField(Field):
|
||||||
try:
|
try:
|
||||||
return int(value)
|
return int(value)
|
||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
msg = self.error_messages['invalid'] % str(value)
|
msg = self.error_messages['invalid'] % value
|
||||||
raise exceptions.ValidationError(msg)
|
raise exceptions.ValidationError(msg)
|
||||||
|
|
||||||
def validate(self, value, model_instance):
|
def validate(self, value, model_instance):
|
||||||
|
@ -582,7 +582,7 @@ class BooleanField(Field):
|
||||||
return True
|
return True
|
||||||
if value in ('f', 'False', '0'):
|
if value in ('f', 'False', '0'):
|
||||||
return False
|
return False
|
||||||
msg = self.error_messages['invalid'] % str(value)
|
msg = self.error_messages['invalid'] % value
|
||||||
raise exceptions.ValidationError(msg)
|
raise exceptions.ValidationError(msg)
|
||||||
|
|
||||||
def get_prep_lookup(self, lookup_type, value):
|
def get_prep_lookup(self, lookup_type, value):
|
||||||
|
@ -686,8 +686,6 @@ class DateField(Field):
|
||||||
if isinstance(value, datetime.date):
|
if isinstance(value, datetime.date):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
value = smart_str(value)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
parsed = parse_date(value)
|
parsed = parse_date(value)
|
||||||
if parsed is not None:
|
if parsed is not None:
|
||||||
|
@ -779,8 +777,6 @@ class DateTimeField(DateField):
|
||||||
value = timezone.make_aware(value, default_timezone)
|
value = timezone.make_aware(value, default_timezone)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
value = smart_str(value)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
parsed = parse_datetime(value)
|
parsed = parse_datetime(value)
|
||||||
if parsed is not None:
|
if parsed is not None:
|
||||||
|
@ -862,7 +858,7 @@ class DecimalField(Field):
|
||||||
try:
|
try:
|
||||||
return decimal.Decimal(value)
|
return decimal.Decimal(value)
|
||||||
except decimal.InvalidOperation:
|
except decimal.InvalidOperation:
|
||||||
msg = self.error_messages['invalid'] % str(value)
|
msg = self.error_messages['invalid'] % value
|
||||||
raise exceptions.ValidationError(msg)
|
raise exceptions.ValidationError(msg)
|
||||||
|
|
||||||
def _format(self, value):
|
def _format(self, value):
|
||||||
|
@ -967,7 +963,7 @@ class FloatField(Field):
|
||||||
try:
|
try:
|
||||||
return float(value)
|
return float(value)
|
||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
msg = self.error_messages['invalid'] % str(value)
|
msg = self.error_messages['invalid'] % value
|
||||||
raise exceptions.ValidationError(msg)
|
raise exceptions.ValidationError(msg)
|
||||||
|
|
||||||
def formfield(self, **kwargs):
|
def formfield(self, **kwargs):
|
||||||
|
@ -1002,7 +998,7 @@ class IntegerField(Field):
|
||||||
try:
|
try:
|
||||||
return int(value)
|
return int(value)
|
||||||
except (TypeError, ValueError):
|
except (TypeError, ValueError):
|
||||||
msg = self.error_messages['invalid'] % str(value)
|
msg = self.error_messages['invalid'] % value
|
||||||
raise exceptions.ValidationError(msg)
|
raise exceptions.ValidationError(msg)
|
||||||
|
|
||||||
def formfield(self, **kwargs):
|
def formfield(self, **kwargs):
|
||||||
|
@ -1107,7 +1103,7 @@ class NullBooleanField(Field):
|
||||||
return True
|
return True
|
||||||
if value in ('f', 'False', '0'):
|
if value in ('f', 'False', '0'):
|
||||||
return False
|
return False
|
||||||
msg = self.error_messages['invalid'] % str(value)
|
msg = self.error_messages['invalid'] % value
|
||||||
raise exceptions.ValidationError(msg)
|
raise exceptions.ValidationError(msg)
|
||||||
|
|
||||||
def get_prep_lookup(self, lookup_type, value):
|
def get_prep_lookup(self, lookup_type, value):
|
||||||
|
@ -1228,8 +1224,6 @@ class TimeField(Field):
|
||||||
# database backend (e.g. Oracle), so we'll be accommodating.
|
# database backend (e.g. Oracle), so we'll be accommodating.
|
||||||
return value.time()
|
return value.time()
|
||||||
|
|
||||||
value = smart_str(value)
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
parsed = parse_time(value)
|
parsed = parse_time(value)
|
||||||
if parsed is not None:
|
if parsed is not None:
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
# -*- encoding: utf-8 -*-
|
||||||
from django.core.exceptions import ValidationError
|
from django.core.exceptions import ValidationError
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.utils.unittest import TestCase
|
from django.utils.unittest import TestCase
|
||||||
|
@ -12,8 +13,8 @@ class ValidationMessagesTest(TestCase):
|
||||||
|
|
||||||
def test_autofield_field_raises_error_message(self):
|
def test_autofield_field_raises_error_message(self):
|
||||||
f = models.AutoField(primary_key=True)
|
f = models.AutoField(primary_key=True)
|
||||||
self._test_validation_messages(f, 'foo',
|
self._test_validation_messages(f, u'fõo',
|
||||||
[u"'foo' value must be an integer."])
|
[u"'fõo' value must be an integer."])
|
||||||
# primary_key must be True. Refs #12467.
|
# primary_key must be True. Refs #12467.
|
||||||
with self.assertRaisesRegexp(AssertionError,
|
with self.assertRaisesRegexp(AssertionError,
|
||||||
"AutoFields must have primary_key=True."):
|
"AutoFields must have primary_key=True."):
|
||||||
|
@ -21,33 +22,33 @@ class ValidationMessagesTest(TestCase):
|
||||||
|
|
||||||
def test_integer_field_raises_error_message(self):
|
def test_integer_field_raises_error_message(self):
|
||||||
f = models.IntegerField()
|
f = models.IntegerField()
|
||||||
self._test_validation_messages(f, 'foo',
|
self._test_validation_messages(f, u'fõo',
|
||||||
[u"'foo' value must be an integer."])
|
[u"'fõo' value must be an integer."])
|
||||||
|
|
||||||
def test_boolean_field_raises_error_message(self):
|
def test_boolean_field_raises_error_message(self):
|
||||||
f = models.BooleanField()
|
f = models.BooleanField()
|
||||||
self._test_validation_messages(f, 'foo',
|
self._test_validation_messages(f, u'fõo',
|
||||||
[u"'foo' value must be either True or False."])
|
[u"'fõo' value must be either True or False."])
|
||||||
|
|
||||||
def test_float_field_raises_error_message(self):
|
def test_float_field_raises_error_message(self):
|
||||||
f = models.FloatField()
|
f = models.FloatField()
|
||||||
self._test_validation_messages(f, 'foo',
|
self._test_validation_messages(f, u'fõo',
|
||||||
[u"'foo' value must be a float."])
|
[u"'fõo' value must be a float."])
|
||||||
|
|
||||||
def test_decimal_field_raises_error_message(self):
|
def test_decimal_field_raises_error_message(self):
|
||||||
f = models.DecimalField()
|
f = models.DecimalField()
|
||||||
self._test_validation_messages(f, 'foo',
|
self._test_validation_messages(f, u'fõo',
|
||||||
[u"'foo' value must be a decimal number."])
|
[u"'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.NullBooleanField()
|
||||||
self._test_validation_messages(f, 'foo',
|
self._test_validation_messages(f, u'fõo',
|
||||||
[u"'foo' value must be either None, True or False."])
|
[u"'fõo' value must be either None, True or False."])
|
||||||
|
|
||||||
def test_date_field_raises_error_message(self):
|
def test_date_field_raises_error_message(self):
|
||||||
f = models.DateField()
|
f = models.DateField()
|
||||||
self._test_validation_messages(f, 'foo',
|
self._test_validation_messages(f, u'fõo',
|
||||||
[u"'foo' value has an invalid date format. "
|
[u"'fõo' value has an invalid date format. "
|
||||||
u"It must be in YYYY-MM-DD format."])
|
u"It must be in YYYY-MM-DD format."])
|
||||||
|
|
||||||
self._test_validation_messages(f, 'aaaa-10-10',
|
self._test_validation_messages(f, 'aaaa-10-10',
|
||||||
|
@ -65,8 +66,8 @@ class ValidationMessagesTest(TestCase):
|
||||||
def test_datetime_field_raises_error_message(self):
|
def test_datetime_field_raises_error_message(self):
|
||||||
f = models.DateTimeField()
|
f = models.DateTimeField()
|
||||||
# Wrong format
|
# Wrong format
|
||||||
self._test_validation_messages(f, 'foo',
|
self._test_validation_messages(f, u'fõo',
|
||||||
[u"'foo' value has an invalid format. It must be "
|
[u"'fõo' value has an invalid format. It must be "
|
||||||
u"in YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] format."])
|
u"in YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] format."])
|
||||||
|
|
||||||
# Correct format but invalid date
|
# Correct format but invalid date
|
||||||
|
@ -83,8 +84,8 @@ class ValidationMessagesTest(TestCase):
|
||||||
def test_time_field_raises_error_message(self):
|
def test_time_field_raises_error_message(self):
|
||||||
f = models.TimeField()
|
f = models.TimeField()
|
||||||
# Wrong format
|
# Wrong format
|
||||||
self._test_validation_messages(f, 'foo',
|
self._test_validation_messages(f, u'fõo',
|
||||||
[u"'foo' value has an invalid format. It must be in "
|
[u"'fõo' value has an invalid format. It must be in "
|
||||||
u"HH:MM[:ss[.uuuuuu]] format."])
|
u"HH:MM[:ss[.uuuuuu]] format."])
|
||||||
|
|
||||||
# Correct format but invalid time
|
# Correct format but invalid time
|
||||||
|
|
Loading…
Reference in New Issue