11import pycountry
22import rest_framework .exceptions
3+ import rest_framework .serializers
34
45import user .models
56
@@ -25,47 +26,68 @@ def __call__(self, value):
2526 raise exc
2627
2728
28- class OtherFieldValidator :
29+ class OtherFieldValidator ( rest_framework . serializers . Serializer ) :
2930 """
30- Validator for JSON fields containing :
31- - age (required, integer between 0 and 100)
32- - country (required, string with an ISO 3166-1 alpha-2 country code )
31+ Validates JSON fields:
32+ - age (required, 0- 100)
33+ - country (required, valid ISO 3166-1 alpha-2)
3334 """
3435
35- error_messages = {
36- 'invalid_type' : 'Must be a JSON object.' ,
37- 'missing_field' : 'This field is required.' ,
38- 'age_type' : 'Must be an integer.' ,
39- 'age_range' : 'Must be between 0 and 100.' ,
40- 'country_format' : 'Must be a 2-letter ISO code.' ,
41- 'country_invalid' : 'Invalid ISO 3166-1 alpha-2 country code.' ,
42- }
36+ country_codes = {c .alpha_2 for c in pycountry .countries }
37+ print (country_codes )
38+
39+ age = rest_framework .serializers .IntegerField (
40+ required = True ,
41+ min_value = 0 ,
42+ max_value = 100 ,
43+ error_messages = {
44+ 'required' : 'This field is required.' ,
45+ 'invalid' : 'Must be an integer.' ,
46+ 'min_value' : 'Must be between 0 and 100.' ,
47+ 'max_value' : 'Must be between 0 and 100.' ,
48+ },
49+ )
50+
51+ country = rest_framework .serializers .CharField (
52+ required = True ,
53+ max_length = 2 ,
54+ min_length = 2 ,
55+ error_messages = {
56+ 'required' : 'This field is required.' ,
57+ 'blank' : 'Must be a 2-letter ISO code.' ,
58+ 'max_length' : 'Must be a 2-letter ISO code.' ,
59+ 'min_length' : 'Must be a 2-letter ISO code.' ,
60+ },
61+ )
62+
63+ def validate_country (self , value ):
64+ country = value .upper ()
65+ if country not in self .country_codes :
66+ raise rest_framework .serializers .ValidationError (
67+ 'Invalid ISO 3166-1 alpha-2 country code.' ,
68+ )
69+
70+ return country
4371
4472 def __call__ (self , value ):
4573 if not isinstance (value , dict ):
46- raise rest_framework .exceptions .ValidationError (
47- self . error_messages [ 'invalid_type' ] ,
74+ raise rest_framework .serializers .ValidationError (
75+ { 'non_field_errors' : [ 'Must be a JSON object' ]} ,
4876 )
4977
50- errors = {}
51-
52- # Validate the 'age' field
53- age = value .get ('age' )
54- if age is None :
55- errors ['age' ] = self .error_messages ['missing_field' ]
56- elif not isinstance (age , int ):
57- errors ['age' ] = self .error_messages ['age_type' ]
58- elif not (0 <= age <= 100 ):
59- errors ['age' ] = self .error_messages ['age_range' ]
60-
61- # Validate the 'country' field
62- country_code = value .get ('country' )
63- if country_code is None :
64- errors ['country' ] = self .error_messages ['missing_field' ]
65- elif not (isinstance (country_code , str ) and len (country_code ) == 2 ):
66- errors ['country' ] = self .error_messages ['country_format' ]
67- elif not pycountry .countries .get (alpha_2 = country_code .upper ()):
68- errors ['country' ] = self .error_messages ['country_invalid' ]
69-
70- if errors :
71- raise rest_framework .exceptions .ValidationError (errors )
78+ missing_fields = [
79+ field
80+ for field in self .fields
81+ if field not in value or value .get (field ) in (None , '' )
82+ ]
83+
84+ if missing_fields :
85+ raise rest_framework .serializers .ValidationError (
86+ {field : 'This field is required.' for field in missing_fields },
87+ )
88+
89+ serializer = self .__class__ (data = value )
90+ if not serializer .is_valid ():
91+ raise rest_framework .serializers .ValidationError (serializer .errors )
92+
93+ return value
0 commit comments