Index: ind/in_states.py
===================================================================
--- ind/in_states.py    (revision 0)
+++ ind/in_states.py    (revision 0)
@@ -0,0 +1,84 @@
+"""
+A mapping of state misspellings/abbreviations to normalized abbreviations, and
+an alphabetical list of states for use as `choices` in a formfield.
+
+This exists in this standalone file so that it's only imported into memory
+when explicitly needed.
+"""
+
+STATE_CHOICES = (
+    'KA', 'Karnataka',
+    'AP', 'Andhra Pradesh',
+    'KL', 'Kerala',
+    'TN', 'Tamil Nadu',
+    'MH', 'Maharashtra',
+    'UP', 'Uttar Pradesh',
+    'GA', 'Goa',
+    'GJ', 'Gujarat',
+    'RJ', 'Rajasthan',
+    'HP', 'Himachal Pradesh',
+    'JK', 'Jammu and Kashmir',
+    'AR', 'Arunachal Pradesh',
+    'AS', 'Assam',
+    'BR', 'Bihar',
+    'CG', 'Chattisgarh',
+    'HR', 'Haryana',
+    'JH', 'Jharkhand',
+    'MP', 'Madhya Pradesh',
+    'MN', 'Manipur',
+    'ML', 'Meghalaya',
+    'MZ', 'Mizoram',
+    'NL', 'Nagaland',
+    'OR', 'Orissa',
+    'PB', 'Punjab',
+    'SK', 'Sikkim',
+    'TR', 'Tripura',
+    'UA', 'Uttarakhand',
+    'WB', 'West Bengal',
+    #Union Territories
+    'AN', 'Andaman and Nicobar',
+    'CH', 'Chandigarh',
+    'DN', 'Dadra and Nagar Haveli',
+    'DD', 'Daman and Diu',
+    'DL', 'Delhi',
+    'LD', 'Lakshadweep',
+    'PY', 'Pondicherry',
+)
+
+STATES_NORMALIZED = {
+    'ka': 'KA',
+    'karnatka': 'KA',
+    'tn': 'TN',
+    'tamilnad': 'TN',
+    'tamilnadu': 'TN',
+    'andra pradesh': 'AP',
+    'andrapradesh': 'AP',
+    'andhrapradesh': 'AP',
+    'maharastra': 'MH',
+    'mh': 'MH',
+    'ap': 'AP',
+    'dl': 'DL',
+    'dd': 'DD',
+    'br': 'BR',
+    'ar': 'AR',
+    'sk': 'SK',
+    'kl': 'KL',
+    'ga': 'GA',
+    'rj': 'RJ',
+    'rajastan': 'RJ',
+    'rajasthan': 'RJ',
+    'hp': 'HP',
+    'ua': 'UA',
+    'up': 'UP',
+    'mp': 'MP',
+    'mz': 'MZ',
+    'bengal': 'WB',
+    'westbengal': 'WB',
+    'mizo': 'MZ',
+    'orisa': 'OR',
+    'odisa': 'OR',
+    'or': 'OR',
+    'ar': 'AR',
+
+    }
+

Index: ind/__init__.py
===================================================================
--- ind/__init__.py     (revision 0)
+++ ind/__init__.py     (revision 0)
@@ -0,0 +1 @@
+# __init__.py

Index: ind/forms.py
===================================================================
--- ind/forms.py        (revision 0)
+++ ind/forms.py        (revision 0)
@@ -0,0 +1,48 @@
+"""
+India-specific Form helpers
+"""
+
+from django.newforms import ValidationError
+from django.newforms.fields import Field, RegexField, Select, EMPTY_VALUES
+from django.utils.encoding import smart_unicode
+from django.utils.translation import gettext
+import re
+
+
+class INZipCodeField(RegexField):
+    def __init__(self, *args, **kwargs):
+        super(INZipCodeField, self).__init__(r'^\d{6}$',
+            max_length=None, min_length=None,
+            error_message=gettext(u'Enter a zip code in the format XXXXXXX.'),
+            *args, **kwargs)
+
+
+class INStateField(Field):
+    """
+    A form field that validates its input is a Indian state name or abbreviatio                                              n.
+    It normalizes the input to the standard two-leter vehicle registration
+    abbreviation for the given state or union territory
+    """
+    def clean(self, value):
+        from in_states import STATES_NORMALIZED # relative import
+        super(INStateField, self).clean(value)
+        if value in EMPTY_VALUES:
+            return u''
+        try:
+            value = value.strip().lower()
+        except AttributeError:
+            pass
+        else:
+            try:
+                return STATES_NORMALIZED[value.strip().lower()].decode('ascii')
+            except KeyError:
+                pass
+        raise ValidationError(u'Enter a Indian state or territory.')
+
+class INStateSelect(Select):
+    """
+    A Select widget that uses a list of Indian states/territories as its choice                                              s.
+    """
+    def __init__(self, attrs=None):
+        from in_states import STATE_CHOICES # relative import
+        super(INStateSelect, self).__init__(attrs, choices=STATE_CHOICES)
