1+ from __future__ import print_function
2+
13import django
24from django .core import validators
35from django .core .exceptions import NON_FIELD_ERRORS , ValidationError
79 from django .utils .translation import ugettext as _
810else :
911 from django .utils .translation import gettext as _
10-
12+
1113
1214def field_to_str (fields ):
1315 return _ (
@@ -38,12 +40,12 @@ class FieldValidationMixin:
3840 # If condition is True ensure none of the fields are provided
3941 CONDITIONAL_REQUIRED_EMPTY_FIELDS = []
4042
41- ERROR_HANDLERS = {' form' : ValidationError }
43+ ERROR_HANDLERS = {" form" : ValidationError }
4244
4345 EMPTY_VALUES = list (validators .EMPTY_VALUES )
4446
4547 @staticmethod
46- def _error_as_dict (field , msg , code = ' required' , error_class = ValidationError ):
48+ def _error_as_dict (field , msg , code = " required" , error_class = ValidationError ):
4749 return {field : error_class (_ (msg ), code = code )}
4850
4951 def _validate_only_one_option (self , selections , found_keys ):
@@ -54,27 +56,40 @@ def _validate_only_one_option(self, selections, found_keys):
5456 if key in section :
5557 provided_fields .append (key )
5658 if len (set (provided_fields )) > 1 :
57- msg = f'Please provide only one of: { field_to_str (section )} '
58- error_dict .update (self ._error_as_dict (provided_fields [- 1 ], msg , code = 'invalid' ))
59+ msg = "Please provide only one of: {fields}" .format (
60+ fields = field_to_str (section )
61+ )
62+ error_dict .update (
63+ self ._error_as_dict (provided_fields [- 1 ], msg , code = "invalid" )
64+ )
5965 break
6066 return error_dict
6167
6268 def _clean_conditional_toggle_fields (self , exclude = None , context = None ):
6369 if self .CONDITIONAL_REQUIRED_TOGGLE_FIELDS :
6470 return self ._clean_conditional_fields (
65- exclude , context , field_sets = self .CONDITIONAL_REQUIRED_TOGGLE_FIELDS , validate_one = True ,
71+ exclude ,
72+ context ,
73+ field_sets = self .CONDITIONAL_REQUIRED_TOGGLE_FIELDS ,
74+ validate_one = True ,
6675 )
6776
6877 def _clean_conditional_min_fields (self , exclude = None , context = None ):
6978 if self .CONDITIONAL_REQUIRED_MIN_FIELDS :
7079 return self ._clean_conditional_fields (
71- exclude , context , field_sets = self .CONDITIONAL_REQUIRED_MIN_FIELDS , at_least_one = True ,
80+ exclude ,
81+ context ,
82+ field_sets = self .CONDITIONAL_REQUIRED_MIN_FIELDS ,
83+ at_least_one = True ,
7284 )
7385
7486 def _clean_conditional_empty_fields (self , exclude = None , context = None ):
7587 if self .CONDITIONAL_REQUIRED_EMPTY_FIELDS :
7688 return self ._clean_conditional_fields (
77- exclude , context , field_sets = self .CONDITIONAL_REQUIRED_EMPTY_FIELDS , none_provided = True ,
89+ exclude ,
90+ context ,
91+ field_sets = self .CONDITIONAL_REQUIRED_EMPTY_FIELDS ,
92+ none_provided = True ,
7893 )
7994
8095 def _clean_conditional_fields (
@@ -96,7 +111,9 @@ def _clean_conditional_fields(
96111 for condition , fields in field_sets :
97112 field_names = list (filter (lambda f : f not in exclude , fields ))
98113 if field_names :
99- is_valid_condition = condition if isinstance (condition , bool ) else False
114+ is_valid_condition = (
115+ condition if isinstance (condition , bool ) else False
116+ )
100117 if callable (condition ):
101118 is_valid_condition = condition (self )
102119
@@ -110,40 +127,62 @@ def _clean_conditional_fields(
110127 if not field_value_map and not none_provided :
111128 if len (fields ) > 1 :
112129 msg = (
113- f'Please provide a valid value for the following fields: '
114- f'{ field_to_str (fields )} ' if not validate_one else
115- f'Please provide a valid value for any of the following fields: '
116- f'{ field_to_str (fields )} '
130+ "Please provide a valid value for the following fields: "
131+ "{fields}"
132+ if not validate_one
133+ else "Please provide a valid value for any of the following fields: "
134+ "{fields}" .format (fields = field_to_str (fields ))
135+ )
136+ errors .update (
137+ self ._error_as_dict (NON_FIELD_ERRORS , msg )
117138 )
118- errors .update (self ._error_as_dict (NON_FIELD_ERRORS , msg ))
119139 else :
120- msg = f'Please provide a value for: "{ fields [- 1 ]} "'
121- errors .update (self ._error_as_dict (fields [- 1 ], msg ))
140+ field = fields [0 ]
141+ msg = (
142+ 'Please provide a value for: "{field}"' .format (
143+ field = field
144+ )
145+ )
146+ errors .update (self ._error_as_dict (field , msg ))
122147 break
123148
124149 if field_value_map and none_provided :
125- msg = (
126- f'Please omit changes to the following fields: '
127- f'{ field_to_str (fields )} '
150+ msg = "Please omit changes to the following fields: {fields}" .format (
151+ fields = field_to_str (fields )
152+ )
153+ errors .update (
154+ self ._error_as_dict (NON_FIELD_ERRORS , msg )
128155 )
129- errors .update (self ._error_as_dict (NON_FIELD_ERRORS , msg ))
130156 break
131157
132158 missing_fields = [
133- field_name for field_name in fields
159+ field_name
160+ for field_name in fields
134161 if field_name not in field_value_map .keys ()
135162 ]
136163
137- if not validate_one and not at_least_one and not none_provided :
164+ if (
165+ not validate_one
166+ and not at_least_one
167+ and not none_provided
168+ ):
138169 for missing_field in missing_fields :
139- msg = f'Please provide a value for: "{ missing_field } "'
140- errors .update (self ._error_as_dict (missing_field , msg ))
170+ msg = 'Please provide a value for: "{missing_field}"' .format (
171+ missing_field = missing_field
172+ )
173+ errors .update (
174+ self ._error_as_dict (missing_field , msg )
175+ )
141176
142- elif validate_one and len (fields ) - 1 != len (list (missing_fields )):
143- msg = (
144- f'Please provide only one of the following fields: { field_to_str (fields )} '
177+ elif validate_one and len (fields ) - 1 != len (
178+ list (missing_fields )
179+ ):
180+ msg = "Please provide only one of the following fields: {fields}" .format (
181+ fields = field_to_str (fields )
182+ )
183+ errors .update (
184+ self ._error_as_dict (NON_FIELD_ERRORS , msg )
145185 )
146- errors .update (self ._error_as_dict (NON_FIELD_ERRORS , msg ))
147186
148187 except ValueError :
149188 pass
@@ -154,12 +193,14 @@ def _clean_conditional_fields(
154193 def _clean_required_and_optional_fields (self , exclude = None , context = None ):
155194 """Provide extra validation for fields that are required and single selection fields."""
156195 exclude = exclude or []
157- if any ([
158- self .REQUIRED_TOGGLE_FIELDS ,
159- self .REQUIRED_MIN_FIELDS ,
160- self .REQUIRED_FIELDS ,
161- self .OPTIONAL_TOGGLE_FIELDS ,
162- ]):
196+ if any (
197+ [
198+ self .REQUIRED_TOGGLE_FIELDS ,
199+ self .REQUIRED_MIN_FIELDS ,
200+ self .REQUIRED_FIELDS ,
201+ self .OPTIONAL_TOGGLE_FIELDS ,
202+ ]
203+ ):
163204 error_class = self .ERROR_HANDLERS .get (context , ValueError )
164205 found = []
165206 errors = {}
@@ -170,7 +211,9 @@ def _clean_required_and_optional_fields(self, exclude=None, context=None):
170211 raw_value = getattr (self , f .attname )
171212 if f .name in self .REQUIRED_FIELDS :
172213 if raw_value in f .empty_values and not f .has_default ():
173- msg = f'Please provide a value for: "{ f .name } ".'
214+ msg = 'Please provide a value for: "{field_name}".' .format (
215+ field_name = f .name
216+ )
174217 errors .update (self ._error_as_dict (f .name , msg ))
175218
176219 for required_min_field in self .REQUIRED_MIN_FIELDS :
@@ -179,7 +222,10 @@ def _clean_required_and_optional_fields(self, exclude=None, context=None):
179222 if raw_value not in f .empty_values :
180223 found .append ({f .name : raw_value })
181224 elif raw_value in f .empty_values and f .has_default ():
182- if isinstance (f , models .CharField ) and f .get_default () not in f .empty_values :
225+ if (
226+ isinstance (f , models .CharField )
227+ and f .get_default () not in f .empty_values
228+ ):
183229 found .append ({f .name : f .get_default ()})
184230
185231 for required_toggle_field in self .REQUIRED_TOGGLE_FIELDS :
@@ -188,52 +234,74 @@ def _clean_required_and_optional_fields(self, exclude=None, context=None):
188234 if raw_value not in f .empty_values :
189235 found .append ({f .name : raw_value })
190236 elif raw_value in f .empty_values and f .has_default ():
191- if isinstance (f , models .CharField ) and f .get_default () not in f .empty_values :
237+ if (
238+ isinstance (f , models .CharField )
239+ and f .get_default () not in f .empty_values
240+ ):
192241 found .append ({f .name : f .get_default ()})
193242
194243 for optional_toggle_field in self .OPTIONAL_TOGGLE_FIELDS :
195- if f .name in optional_toggle_field and raw_value not in f .empty_values :
244+ if (
245+ f .name in optional_toggle_field
246+ and raw_value not in f .empty_values
247+ ):
196248 optional .append ({f .name : raw_value })
197249
198250 if self .REQUIRED_MIN_FIELDS :
199251 if not found :
200- fields_str = '\n , ' .join ([
201- field_to_str (fields ) for fields in self .REQUIRED_MIN_FIELDS
202- ])
203- fields_str = f'\n { fields_str } ' if len (self .REQUIRED_MIN_FIELDS ) > 1 else fields_str
204- msg = f'Please provide a valid value for any of the following fields: { fields_str } '
252+ fields_str = "\n , " .join (
253+ [field_to_str (fields ) for fields in self .REQUIRED_MIN_FIELDS ]
254+ )
255+ fields_str = (
256+ "\n {fields}" .format (fields = fields_str )
257+ if len (self .REQUIRED_MIN_FIELDS ) > 1
258+ else fields_str
259+ )
260+ msg = "Please provide a valid value for any of the following fields: {fields}" .format (
261+ fields = fields_str
262+ )
205263 errors .update (self ._error_as_dict (NON_FIELD_ERRORS , msg ))
206264
207265 if self .REQUIRED_TOGGLE_FIELDS :
208266 if not found :
209- fields_str = '\n , ' .join ([
210- field_to_str (fields ) for fields in self .REQUIRED_TOGGLE_FIELDS
211- ])
212- fields_str = f'\n { fields_str } ' if len (self .REQUIRED_TOGGLE_FIELDS ) > 1 else fields_str
213- msg = f'Please provide a valid value for any of the following fields: { fields_str } '
267+ fields_str = "\n , " .join (
268+ [field_to_str (fields ) for fields in self .REQUIRED_TOGGLE_FIELDS ]
269+ )
270+ fields_str = (
271+ "\n {fields}" .format (fields = fields_str )
272+ if len (self .REQUIRED_TOGGLE_FIELDS ) > 1
273+ else fields_str
274+ )
275+ msg = "Please provide a valid value for any of the following fields: {fields}" .format (
276+ fields = fields_str
277+ )
214278 errors .update (self ._error_as_dict (NON_FIELD_ERRORS , msg ))
215279 else :
216280 found_keys = [k for item in found for k in item .keys ()]
217281 errors .update (
218- self ._validate_only_one_option (self .REQUIRED_TOGGLE_FIELDS , found_keys ),
282+ self ._validate_only_one_option (
283+ self .REQUIRED_TOGGLE_FIELDS , found_keys
284+ ),
219285 )
220286
221287 if self .OPTIONAL_TOGGLE_FIELDS :
222288 if optional :
223289 optional_keys = [k for item in optional for k in item .keys ()]
224290 errors .update (
225- self ._validate_only_one_option (self .OPTIONAL_TOGGLE_FIELDS , optional_keys ),
291+ self ._validate_only_one_option (
292+ self .OPTIONAL_TOGGLE_FIELDS , optional_keys
293+ ),
226294 )
227295
228296 if errors :
229297 raise error_class (errors )
230298
231299 def clean_fields (self , exclude = None ):
232- self ._clean_conditional_toggle_fields (exclude = exclude , context = ' form' )
233- self ._clean_conditional_min_fields (exclude = exclude , context = ' form' )
234- self ._clean_conditional_empty_fields (exclude = exclude , context = ' form' )
235- self ._clean_conditional_fields (exclude = exclude , context = ' form' )
236- self ._clean_required_and_optional_fields (exclude = exclude , context = ' form' )
300+ self ._clean_conditional_toggle_fields (exclude = exclude , context = " form" )
301+ self ._clean_conditional_min_fields (exclude = exclude , context = " form" )
302+ self ._clean_conditional_empty_fields (exclude = exclude , context = " form" )
303+ self ._clean_conditional_fields (exclude = exclude , context = " form" )
304+ self ._clean_required_and_optional_fields (exclude = exclude , context = " form" )
237305 return super (FieldValidationMixin , self ).clean_fields (exclude = exclude )
238306
239307 def save (self , * args , ** kwargs ):
0 commit comments