Code

Ticket #1553: fields.diff

File fields.diff, 9.2 KB (added by Nebojsa Djordjevic <nesh at studioquattro dot co dot yu>, 8 years ago)

patch for db/models/fields/init.py

Line 
1Index: /store/django_no_magic/django/db/models/fields/__init__.py
2===================================================================
3--- /store/django_no_magic/django/db/models/fields/__init__.py  (revision 2602)
4+++ /store/django_no_magic/django/db/models/fields/__init__.py  (working copy)
5@@ -112,6 +112,9 @@
6         """
7         if not self.blank and not field_data:
8             return [gettext_lazy('This field is required.')]
9+        # XXX IMHO this is the place for NULL validation, to_python will return '' (blank) or None as appropriate
10+        if not self.null and field_data is None:
11+            return [gettext_lazy('This field is required.')]
12         try:
13             self.validate(field_data, all_data)
14         except validators.ValidationError, e:
15@@ -331,6 +334,8 @@
16     def __init__(self, *args, **kwargs):
17         assert kwargs.get('primary_key', False) is True, "%ss must have primary_key=True." % self.__class__.__name__
18         kwargs['blank'] = True
19+        # added because validators
20+        kwargs['null'] = True
21         Field.__init__(self, *args, **kwargs)
22 
23     def to_python(self, value):
24@@ -368,7 +373,10 @@
25         Field.__init__(self, *args, **kwargs)
26 
27     def to_python(self, value):
28+        if value is None:
29+            raise validators.ValidationError, gettext("This value can not be None.")
30         if value in (True, False): return value
31+        if value == '': return False
32         if value is 't': return True
33         if value is 'f': return False
34         raise validators.ValidationError, gettext("This value must be either True or False.")
35@@ -383,12 +391,13 @@
36     def to_python(self, value):
37         if isinstance(value, basestring):
38             return value
39-        if value is None:
40-            if self.null:
41-                return value
42-            else:
43-                raise validators.ValidationError, gettext_lazy("This field cannot be null.")
44+        if value is None: return value
45         return str(value)
46+   
47+    def validate(self, field_data, all_data):
48+        if not field_data: return
49+        if self.maxlength < len(field_data):
50+            raise validators.ValidationError, gettext_lazy("Maximum string length exceeded.")
51 
52 # TODO: Maybe move this into contrib, because it's specialized.
53 class CommaSeparatedIntegerField(CharField):
54@@ -395,6 +404,21 @@
55     def get_manipulator_field_objs(self):
56         return [forms.CommaSeparatedIntegerField]
57 
58+    def to_python(self, value):
59+        value = super(CommaSeparatedIntegerField, self).to_python(value)
60+        if not value: return []
61+        try:
62+            return [int(l) for l in value.split(',')]
63+        except (TypeError, ValueError):
64+            raise ValidationError, gettext("Enter a whole number.")
65+
66+    def validate(self, field_data, all_data):
67+        if not field_data: return
68+        # XXX hmmm, I presume that maxlength here means the maximum entries
69+        if self.maxlength < len(field_data):
70+            raise validators.ValidationError, gettext_lazy("Exceeded maximum number of entries.")
71+
72+
73 class DateField(Field):
74     empty_strings_allowed = False
75     def __init__(self, verbose_name=None, name=None, auto_now=False, auto_now_add=False, **kwargs):
76@@ -406,6 +430,7 @@
77         Field.__init__(self, verbose_name, name, **kwargs)
78 
79     def to_python(self, value):
80+        if value is None or value == '': return None
81         if isinstance(value, datetime.datetime):
82             return value.date()
83         if isinstance(value, datetime.date):
84@@ -457,6 +482,7 @@
85 
86 class DateTimeField(DateField):
87     def to_python(self, value):
88+        if value is None or value == '': return None
89         if isinstance(value, datetime.datetime):
90             return value
91         if isinstance(value, datetime.date):
92@@ -625,6 +651,18 @@
93     def get_manipulator_field_objs(self):
94         return [curry(forms.FloatField, max_digits=self.max_digits, decimal_places=self.decimal_places)]
95 
96+    def to_python(self, value):
97+        import decimal
98+        if value is None or value == '': return None
99+        try:
100+            return decimal.Decimal(value)
101+        except (TypeError, ValueError):
102+            raise validators.ValidationError, gettext_lazy("Enter a float number.")
103+
104+    def validate(self, field_data, all_data):
105+        if len('%.0f' % abs(field_data)) > self.max_digits:
106+            raise validators.ValidationError, gettext_lazy("Too many digits.")
107+
108 class ImageField(FileField):
109     def __init__(self, verbose_name=None, name=None, width_field=None, height_field=None, **kwargs):
110         self.width_field, self.height_field = width_field, height_field
111@@ -659,6 +697,13 @@
112     def get_manipulator_field_objs(self):
113         return [forms.IntegerField]
114 
115+    def to_python(self, value):
116+        if value is None or value == '': return None
117+        try:
118+            return int(value)
119+        except (TypeError, ValueError):
120+            raise validators.ValidationError, gettext_lazy("Enter a whole number.")
121+
122 class IPAddressField(Field):
123     def __init__(self, *args, **kwargs):
124         kwargs['maxlength'] = 15
125@@ -678,6 +723,13 @@
126     def get_manipulator_field_objs(self):
127         return [forms.NullBooleanField]
128 
129+    def to_python(self, value):
130+        if value is None or value == '': return None
131+        if value in (True, False): return value
132+        if value is 't': return True
133+        if value is 'f': return False
134+        raise validators.ValidationError, gettext("This value must be either True or False.")
135+
136 class PhoneNumberField(IntegerField):
137     def get_manipulator_field_objs(self):
138         return [forms.PhoneNumberField]
139@@ -689,6 +741,17 @@
140     def get_manipulator_field_objs(self):
141         return [forms.PositiveIntegerField]
142 
143+    def to_python(self, value):
144+        if value is None or value == '': return None
145+        try:
146+            return int(value)
147+        except (TypeError, ValueError):
148+            raise validators.ValidationError, gettext_lazy("Enter a whole number.")
149+
150+    def validate(self, field_data, all_data):
151+        if field_data < 0:
152+            raise validators.ValidationError, gettext_lazy("Enter a whole positive number.")
153+
154 class PositiveSmallIntegerField(IntegerField):
155     def get_manipulator_field_objs(self):
156         return [forms.PositiveSmallIntegerField]
157@@ -693,6 +756,17 @@
158     def get_manipulator_field_objs(self):
159         return [forms.PositiveSmallIntegerField]
160 
161+    def to_python(self, value):
162+        if value is None or value == '': return None
163+        try:
164+            return int(value)
165+        except (TypeError, ValueError):
166+            raise validators.ValidationError, gettext_lazy("Enter a whole number.")
167+
168+    def validate(self, field_data, all_data):
169+        if field_data < 0:
170+            raise validators.ValidationError, gettext_lazy("Enter a whole positive number.")
171+
172 class SlugField(Field):
173     def __init__(self, *args, **kwargs):
174         kwargs['maxlength'] = 50
175@@ -705,6 +779,9 @@
176     def get_manipulator_field_objs(self):
177         return [forms.TextField]
178 
179+    def validate(self, field_data, all_data):
180+        validators.isSlug(field_data, all_data)
181+
182 class SmallIntegerField(IntegerField):
183     def get_manipulator_field_objs(self):
184         return [forms.SmallIntegerField]
185@@ -709,6 +786,13 @@
186     def get_manipulator_field_objs(self):
187         return [forms.SmallIntegerField]
188 
189+    def to_python(self, value):
190+        if value is None or value == '': return None
191+        try:
192+            return int(value)
193+        except (TypeError, ValueError):
194+            raise validators.ValidationError, gettext_lazy("Enter a whole number.")
195+
196 class TextField(Field):
197     def get_manipulator_field_objs(self):
198         return [forms.LargeTextField]
199@@ -750,6 +834,14 @@
200         val = self._get_val_from_obj(obj)
201         return {self.attname: (val is not None and val.strftime("%H:%M:%S") or '')}
202 
203+    def to_python(self, value):
204+        if value is None or value == '': return None
205+        try:
206+            st = time.strptime(value, '%H:%M:%S')
207+            return datetime.time(st.tm_hour, st.tm_min, st.tm_sec)
208+        except (TypeError, ValueError):
209+            raise validators.ValidationError, gettext_lazy("Enter a whole number.")
210+
211 class URLField(Field):
212     def __init__(self, verbose_name=None, name=None, verify_exists=True, **kwargs):
213         if verify_exists:
214@@ -754,6 +846,7 @@
215     def __init__(self, verbose_name=None, name=None, verify_exists=True, **kwargs):
216         if verify_exists:
217             kwargs.setdefault('validator_list', []).append(validators.isExistingURL)
218+        self.verify_exists = verify_exists
219         Field.__init__(self, verbose_name, name, **kwargs)
220 
221     def get_manipulator_field_objs(self):
222@@ -759,6 +852,16 @@
223     def get_manipulator_field_objs(self):
224         return [forms.URLField]
225 
226+    def to_python(self, value):
227+        if isinstance(value, basestring): return value
228+        if value is None: return value
229+        return str(value)
230+   
231+    def validate(self, field_data, all_data):
232+        validators.isValidURL(field_data, all_data)
233+        if self.verify_exists:
234+            validators.isExistingURL(field_data, all_data)
235+
236 class USStateField(Field):
237     def get_manipulator_field_objs(self):
238         return [forms.USStateField]