Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #18407 -- Made model field's to_python methods fully accept uni…

…code.

When generating error message in to_python, any unicode string
containing non-ascii characters triggered a UnicodeEncodeError for
most field types.
  • Loading branch information...
commit 0dc904979d5b6df78662653d498c91f4d54f36c2 1 parent 473c272
Claude Paroz authored
20  django/db/models/fields/__init__.py
@@ -17,7 +17,7 @@
17 17
 from django.utils.text import capfirst
18 18
 from django.utils import timezone
19 19
 from django.utils.translation import ugettext_lazy as _
20  
-from django.utils.encoding import smart_unicode, force_unicode, smart_str
  20
+from django.utils.encoding import smart_unicode, force_unicode
21 21
 from django.utils.ipv6 import clean_ipv6_address
22 22
 
23 23
 class NOT_PROVIDED:
@@ -530,7 +530,7 @@ def to_python(self, value):
530 530
         try:
531 531
             return int(value)
532 532
         except (TypeError, ValueError):
533  
-            msg = self.error_messages['invalid'] % str(value)
  533
+            msg = self.error_messages['invalid'] % value
534 534
             raise exceptions.ValidationError(msg)
535 535
 
536 536
     def validate(self, value, model_instance):
@@ -582,7 +582,7 @@ def to_python(self, value):
582 582
             return True
583 583
         if value in ('f', 'False', '0'):
584 584
             return False
585  
-        msg = self.error_messages['invalid'] % str(value)
  585
+        msg = self.error_messages['invalid'] % value
586 586
         raise exceptions.ValidationError(msg)
587 587
 
588 588
     def get_prep_lookup(self, lookup_type, value):
@@ -686,8 +686,6 @@ def to_python(self, value):
686 686
         if isinstance(value, datetime.date):
687 687
             return value
688 688
 
689  
-        value = smart_str(value)
690  
-
691 689
         try:
692 690
             parsed = parse_date(value)
693 691
             if parsed is not None:
@@ -779,8 +777,6 @@ def to_python(self, value):
779 777
                 value = timezone.make_aware(value, default_timezone)
780 778
             return value
781 779
 
782  
-        value = smart_str(value)
783  
-
784 780
         try:
785 781
             parsed = parse_datetime(value)
786 782
             if parsed is not None:
@@ -862,7 +858,7 @@ def to_python(self, value):
862 858
         try:
863 859
             return decimal.Decimal(value)
864 860
         except decimal.InvalidOperation:
865  
-            msg = self.error_messages['invalid'] % str(value)
  861
+            msg = self.error_messages['invalid'] % value
866 862
             raise exceptions.ValidationError(msg)
867 863
 
868 864
     def _format(self, value):
@@ -967,7 +963,7 @@ def to_python(self, value):
967 963
         try:
968 964
             return float(value)
969 965
         except (TypeError, ValueError):
970  
-            msg = self.error_messages['invalid'] % str(value)
  966
+            msg = self.error_messages['invalid'] % value
971 967
             raise exceptions.ValidationError(msg)
972 968
 
973 969
     def formfield(self, **kwargs):
@@ -1002,7 +998,7 @@ def to_python(self, value):
1002 998
         try:
1003 999
             return int(value)
1004 1000
         except (TypeError, ValueError):
1005  
-            msg = self.error_messages['invalid'] % str(value)
  1001
+            msg = self.error_messages['invalid'] % value
1006 1002
             raise exceptions.ValidationError(msg)
1007 1003
 
1008 1004
     def formfield(self, **kwargs):
@@ -1107,7 +1103,7 @@ def to_python(self, value):
1107 1103
             return True
1108 1104
         if value in ('f', 'False', '0'):
1109 1105
             return False
1110  
-        msg = self.error_messages['invalid'] % str(value)
  1106
+        msg = self.error_messages['invalid'] % value
1111 1107
         raise exceptions.ValidationError(msg)
1112 1108
 
1113 1109
     def get_prep_lookup(self, lookup_type, value):
@@ -1228,8 +1224,6 @@ def to_python(self, value):
1228 1224
             # database backend (e.g. Oracle), so we'll be accommodating.
1229 1225
             return value.time()
1230 1226
 
1231  
-        value = smart_str(value)
1232  
-
1233 1227
         try:
1234 1228
             parsed = parse_time(value)
1235 1229
             if parsed is not None:
37  tests/modeltests/validation/test_error_messages.py
... ...
@@ -1,3 +1,4 @@
  1
+# -*- encoding: utf-8 -*-
1 2
 from django.core.exceptions import ValidationError
2 3
 from django.db import models
3 4
 from django.utils.unittest import TestCase
@@ -12,8 +13,8 @@ def _test_validation_messages(self, field, value, expected):
12 13
 
13 14
     def test_autofield_field_raises_error_message(self):
14 15
         f = models.AutoField(primary_key=True)
15  
-        self._test_validation_messages(f, 'foo',
16  
-            [u"'foo' value must be an integer."])
  16
+        self._test_validation_messages(f, u'fõo',
  17
+            [u"'fõo' value must be an integer."])
17 18
         # primary_key must be True. Refs #12467.
18 19
         with self.assertRaisesRegexp(AssertionError,
19 20
                 "AutoFields must have primary_key=True."):
@@ -21,33 +22,33 @@ def test_autofield_field_raises_error_message(self):
21 22
 
22 23
     def test_integer_field_raises_error_message(self):
23 24
         f = models.IntegerField()
24  
-        self._test_validation_messages(f, 'foo',
25  
-            [u"'foo' value must be an integer."])
  25
+        self._test_validation_messages(f, u'fõo',
  26
+            [u"'fõo' value must be an integer."])
26 27
 
27 28
     def test_boolean_field_raises_error_message(self):
28 29
         f = models.BooleanField()
29  
-        self._test_validation_messages(f, 'foo',
30  
-            [u"'foo' value must be either True or False."])
  30
+        self._test_validation_messages(f, u'fõo',
  31
+            [u"'fõo' value must be either True or False."])
31 32
 
32 33
     def test_float_field_raises_error_message(self):
33 34
         f = models.FloatField()
34  
-        self._test_validation_messages(f, 'foo',
35  
-            [u"'foo' value must be a float."])
  35
+        self._test_validation_messages(f, u'fõo',
  36
+            [u"'fõo' value must be a float."])
36 37
 
37 38
     def test_decimal_field_raises_error_message(self):
38 39
         f = models.DecimalField()
39  
-        self._test_validation_messages(f, 'foo',
40  
-            [u"'foo' value must be a decimal number."])
  40
+        self._test_validation_messages(f, u'fõo',
  41
+            [u"'fõo' value must be a decimal number."])
41 42
 
42 43
     def test_null_boolean_field_raises_error_message(self):
43 44
         f = models.NullBooleanField()
44  
-        self._test_validation_messages(f, 'foo',
45  
-            [u"'foo' value must be either None, True or False."])
  45
+        self._test_validation_messages(f, u'fõo',
  46
+            [u"'fõo' value must be either None, True or False."])
46 47
 
47 48
     def test_date_field_raises_error_message(self):
48 49
         f = models.DateField()
49  
-        self._test_validation_messages(f, 'foo',
50  
-            [u"'foo' value has an invalid date format. "
  50
+        self._test_validation_messages(f, u'fõo',
  51
+            [u"'fõo' value has an invalid date format. "
51 52
              u"It must be in YYYY-MM-DD format."])
52 53
 
53 54
         self._test_validation_messages(f, 'aaaa-10-10',
@@ -65,8 +66,8 @@ def test_date_field_raises_error_message(self):
65 66
     def test_datetime_field_raises_error_message(self):
66 67
         f = models.DateTimeField()
67 68
         # Wrong format
68  
-        self._test_validation_messages(f, 'foo',
69  
-            [u"'foo' value has an invalid format. It must be "
  69
+        self._test_validation_messages(f, u'fõo',
  70
+            [u"'fõo' value has an invalid format. It must be "
70 71
              u"in YYYY-MM-DD HH:MM[:ss[.uuuuuu]][TZ] format."])
71 72
 
72 73
         # Correct format but invalid date
@@ -83,8 +84,8 @@ def test_datetime_field_raises_error_message(self):
83 84
     def test_time_field_raises_error_message(self):
84 85
         f = models.TimeField()
85 86
         # Wrong format
86  
-        self._test_validation_messages(f, 'foo',
87  
-            [u"'foo' value has an invalid format. It must be in "
  87
+        self._test_validation_messages(f, u'fõo',
  88
+            [u"'fõo' value has an invalid format. It must be in "
88 89
              u"HH:MM[:ss[.uuuuuu]] format."])
89 90
 
90 91
         # Correct format but invalid time

0 notes on commit 0dc9049

Please sign in to comment.
Something went wrong with that request. Please try again.