Using Django to Validate International Postcodes
Join the DZone community and get the full member experience.
Join For FreeProblem
You want to validate a post/zip-code when you only know the country at runtime.
Solution
Use this snippet to dynamically fetch a validation method from Django's suite of "localflavor" form fields using the ISO 3166-1 two character country code.
def get_postcode_validator(country_code): # Django 1.3 uses 'UK' instead of GB - this changes in 1.4 if country_code == 'GB': country_code = 'UK' module_path = 'django.contrib.localflavor.%s' % country_code.lower() try: module = __import__(module_path, fromlist=['forms']) except ImportError: # No forms module for this country return lambda x: x fieldname_variants = ['%sPostcodeField', '%sPostCodeField', '%sPostalCodeField', '%sZipCodeField',] for variant in fieldname_variants: fieldname = variant % country_code.upper() if hasattr(module.forms, fieldname): return getattr(module.forms, fieldname)().clean return lambda x: x
As these validators are from forms, they will raise django.forms.ValidationError if the passed postcode is invalid. Hence your client code should look something like:
from django.forms import ValidationError def is_postcode_valid(postcode, country_code): try: get_postcode_validator(country_code)(postcode) except ValidationError: return False return True
Discussion
As you can see, this is a touch messy as:
- Django 1.3 uses the incorrect code for the UK (it should be 'GB')
- There are a variety of different class names used for the appropriate field. We simply iterate over the possibilities and test to see if the class exists in the forms module.
This code is used within an internal Tangent geocoding webservice.
Published at DZone with permission of David Winterbottom, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.
Comments