Commit 5ed6e7a4 authored by James Bennett's avatar James Bennett
Browse files

Refactor the choices for localflavor's USStateField, and add new US postal...

Refactor the choices for localflavor's USStateField, and add new US postal code support. Fixes #14937 and #9022, refs #10308 and #8425.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@15029 bcc190cf-cafb-0310-a4f2-bffc1f526a37
parent f117b91b
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -111,3 +111,12 @@ class USStateSelect(Select):
    def __init__(self, attrs=None):
        from us_states import STATE_CHOICES
        super(USStateSelect, self).__init__(attrs, choices=STATE_CHOICES)

class USPSSelect(Select):
    """
    A Select widget that uses a list of US Postal Service codes as its
    choices.
    """
    def __init__(self, attrs=None):
        from us_states import USPS_CHOICES
        super(USPSSelect, self).__init__(attrs, choices=USPS_CHOICES)
+10 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@ from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from django.db.models.fields import CharField
from django.contrib.localflavor.us.us_states import STATE_CHOICES
from django.contrib.localflavor.us.us_states import USPS_CHOICES

class USStateField(CharField):

@@ -12,6 +13,15 @@ class USStateField(CharField):
        kwargs['max_length'] = 2
        super(USStateField, self).__init__(*args, **kwargs)

class USPostalCodeField(CharField):

    description = _("U.S. postal code (two uppercase letters)")

    def __init__(self, *args, **kwargs):
        kwargs['choices'] = USPS_CHOICES
        kwargs['max_length'] = 2
        super(USPostalCodeField, self).__init__(*args, **kwargs)

class PhoneNumberField(CharField):

    description = _("Phone number")
+100 −8
Original line number Diff line number Diff line
"""
A mapping of state misspellings/abbreviations to normalized abbreviations, and
an alphabetical list of states for use as `choices` in a formfield.
A mapping of state misspellings/abbreviations to normalized
abbreviations, and alphabetical lists of US states, territories,
military mail regions and non-US states to which the US provides
postal service.

This exists in this standalone file so that it's only imported into memory
when explicitly needed.
"""

STATE_CHOICES = (
# The 48 contiguous states, plus the District of Columbia.
CONTIGUOUS_STATES = (
    ('AL', 'Alabama'),
    ('AZ', 'Arizona'),
    ('AR', 'Arkansas'),
    ('CA', 'California'),
    ('CO', 'Colorado'),
    ('CT', 'Connecticut'),
    ('DE', 'Delaware'),
    ('DC', 'District of Columbia'),
    ('FL', 'Florida'),
    ('GA', 'Georgia'),
    ('ID', 'Idaho'),
    ('IL', 'Illinois'),
    ('IN', 'Indiana'),
    ('IA', 'Iowa'),
    ('KS', 'Kansas'),
    ('KY', 'Kentucky'),
    ('LA', 'Louisiana'),
    ('ME', 'Maine'),
    ('MD', 'Maryland'),
    ('MA', 'Massachusetts'),
    ('MI', 'Michigan'),
    ('MN', 'Minnesota'),
    ('MS', 'Mississippi'),
    ('MO', 'Missouri'),
    ('MT', 'Montana'),
    ('NE', 'Nebraska'),
    ('NV', 'Nevada'),
    ('NH', 'New Hampshire'),
    ('NJ', 'New Jersey'),
    ('NM', 'New Mexico'),
    ('NY', 'New York'),
    ('NC', 'North Carolina'),
    ('ND', 'North Dakota'),
    ('OH', 'Ohio'),
    ('OK', 'Oklahoma'),
    ('OR', 'Oregon'),
    ('PA', 'Pennsylvania'),
    ('RI', 'Rhode Island'),
    ('SC', 'South Carolina'),
    ('SD', 'South Dakota'),
    ('TN', 'Tennessee'),
    ('TX', 'Texas'),
    ('UT', 'Utah'),
    ('VT', 'Vermont'),
    ('VA', 'Virginia'),
    ('WA', 'Washington'),
    ('WV', 'West Virginia'),
    ('WI', 'Wisconsin'),
    ('WY', 'Wyoming'),
)

# All 50 states, plus the District of Columbia.
US_STATES = (
    ('AL', 'Alabama'),
    ('AK', 'Alaska'),
    ('AS', 'American Samoa'),
    ('AZ', 'Arizona'),
    ('AR', 'Arkansas'),
    ('CA', 'California'),
@@ -19,7 +74,6 @@ STATE_CHOICES = (
    ('DC', 'District of Columbia'),
    ('FL', 'Florida'),
    ('GA', 'Georgia'),
    ('GU', 'Guam'),
    ('HI', 'Hawaii'),
    ('ID', 'Idaho'),
    ('IL', 'Illinois'),
@@ -44,12 +98,10 @@ STATE_CHOICES = (
    ('NY', 'New York'),
    ('NC', 'North Carolina'),
    ('ND', 'North Dakota'),
    ('MP', 'Northern Mariana Islands'),
    ('OH', 'Ohio'),
    ('OK', 'Oklahoma'),
    ('OR', 'Oregon'),
    ('PA', 'Pennsylvania'),
    ('PR', 'Puerto Rico'),
    ('RI', 'Rhode Island'),
    ('SC', 'South Carolina'),
    ('SD', 'South Dakota'),
@@ -57,7 +109,6 @@ STATE_CHOICES = (
    ('TX', 'Texas'),
    ('UT', 'Utah'),
    ('VT', 'Vermont'),
    ('VI', 'Virgin Islands'),
    ('VA', 'Virginia'),
    ('WA', 'Washington'),
    ('WV', 'West Virginia'),
@@ -65,6 +116,47 @@ STATE_CHOICES = (
    ('WY', 'Wyoming'),
)

# Non-state territories.
US_TERRITORIES = (
    ('AS', 'American Samoa'),
    ('GU', 'Guam'),
    ('MP', 'Northern Mariana Islands'),
    ('PR', 'Puerto Rico'),
    ('VI', 'Virgin Islands'),
)

# Military postal "states". Note that 'AE' actually encompasses
# Europe, Canada, Africa and the Middle East.
ARMED_FORCES_STATES = (
    ('AA', 'Armed Forces Americas'),
    ('AE', 'Armed Forces Europe'),
    ('AP', 'Armed Forces Pacific'),
)

# Non-US locations serviced by USPS (under Compact of Free
# Association).
COFA_STATES = (
    ('FM', 'Federated States of Micronesia'),
    ('MH', 'Marshall Islands'),
    ('PW', 'Palau'),
)

# Obsolete abbreviations (no longer US territories/USPS service, or
# code changed).
OBSOLETE_STATES = (
    ('CM', 'Commonwealth of the Northern Mariana Islands'), # Is now 'MP'
    ('CZ', 'Panama Canal Zone'),                            # Reverted to Panama 1979
    ('PI', 'Philippine Islands'),                           # Philippine independence 1946
    ('TT', 'Trust Territory of the Pacific Islands'),       # Became the independent COFA states + Northern Mariana Islands 1979-1994
)


# All US states and territories plus DC and military mail.
STATE_CHOICES = US_STATES + US_TERRITORIES + ARMED_FORCES_STATES

# All US Postal Service locations.
USPS_CHOICES = US_STATES + US_TERRITORIES + ARMED_FORCES_STATES + COFA_STATES

STATES_NORMALIZED = {
    'ak': 'AK',
    'al': 'AL',
+65 −0
Original line number Diff line number Diff line
@@ -937,6 +937,11 @@ United States of America (``us``)
    A form ``Select`` widget that uses a list of U.S. states/territories as its
    choices.

.. class:: us.forms.USPSSelect

    A form ``Select`` widget that uses a list of U.S Postal Service
    state, territory and country abbreviations as its choices.

.. class:: us.models.PhoneNumberField

    A :class:`CharField` that checks that the value is a valid U.S.A.-style phone
@@ -947,6 +952,66 @@ United States of America (``us``)
    A model field that forms represent as a ``forms.USStateField`` field and
    stores the two-letter U.S. state abbreviation in the database.

.. class:: us.models.USPostalCodeField

    A model field that forms represent as a ``forms.USPSSelect`` field
    and stores the two-letter U.S Postal Service abbreviation in the
    database.

Additionally, a variety of choice tuples are provided in
``django.contrib.localflavor.us.us_states``, allowing customized model
and form fields, and form presentations, for subsets of U.S states,
territories and U.S Postal Service abbreviations:

.. data:: us.us_states.CONTIGUOUS_STATES

    A tuple of choices of the postal abbreviations for the
    contiguous or "lower 48" states (i.e., all except Alaska and
    Hawaii), plus the District of Columbia.

.. data:: us.us_states.US_STATES

    A tuple of choices of the postal abbreviations for all
    50 U.S. states, plus the District of Columbia.

.. data:: us.us_states.US_TERRITORIES

    A tuple of choices of the postal abbreviations for U.S
    territories: American Samoa, Guam, the Northern Mariana Islands,
    Puerto Rico and the U.S. Virgin Islands.

.. data:: us.us_states.ARMED_FORCES_STATES

    A tuple of choices of the postal abbreviations of the three U.S
    military postal "states": Armed Forces Americas, Armed Forces
    Europe and Armed Forces Pacific.

.. data:: us.us_states.COFA_STATES

    A tuple of choices of the postal abbreviations of the three
    independent nations which, under the Compact of Free Association,
    are served by the U.S. Postal Service: the Federated States of
    Micronesia, the Marshall Islands and Palau.

.. data:: us.us_states.OBSOLETE_STATES

    A tuple of choices of obsolete U.S Postal Service state
    abbreviations: the former abbreviation for the Northern Mariana
    Islands, plus the Panama Canal Zone, the Philippines and the
    former Pacific trust territories.

.. data:: us.us_states.STATE_CHOICES

    A tuple of choices of all postal abbreviations corresponding to U.S states or
    territories, and the District of Columbia..

.. data:: us.us_states.USPS_CHOICES

    A tuple of choices of all postal abbreviations recognized by the
    U.S Postal Service (including all states and territories, the
    District of Columbia, armed forces "states" and independent
    nations serviced by USPS).

Uruguay (``uy``)
================

+46 −0
Original line number Diff line number Diff line
@@ -120,6 +120,52 @@ attribute.

.. _r12634: http://code.djangoproject.com/changeset/12634

Changes to ``USStateField``
===========================

The :mod:`django.contrib.localflavor` application contains collections
of code relevant to specific countries or cultures. One such is
:class:`~django.contrib.localflavor.us.models.USStateField`, which
provides a field for storing the two-letter postal abbreviation of a
U.S. state. This field has consistently caused problems, however,
because it is often used to store the state portion of a U.S postal
address, but not all "states" recognized by the U.S Postal Service are
actually states of the U.S. or even U.S. territory. Several
compromises over the list of choices resulted in some users feeling
the field supported too many locations, while others felt it supported
too few.

In Django 1.3 we're taking a new approach to this problem, implemented
as a pair of changes:

* The choice list for `USStateField` has changed. Previously, it
  consisted of the 50 U.S. states, the District of Columbia and
  U.S. overseas territories. As of Django 1.3 it includes all previous
  choices, plus the U.S. Armed Forces postal codes.

* A new model field,
  :class:`django.contrib.localflavor.us.models.USPostalCodeField`, has
  been added which draws its choices from a list of all postal
  abbreviations recognized by the U.S Postal Service. This includes
  all abbreviations recognized by `USStateField`, plus three
  independent nations -- the Federated States of Micronesia, the
  Republic of the Marshall Islands and the Republic of Palau -- which
  are serviced under treaty by the U.S. postal system. A new form
  widget, :class:`django.contrib.localflavor.us.forms.USPSSelect`, is
  also available and provides the same set of choices.

Additionally, several finer-grained choice tuples are provided which
allow mixing and matching of subsets of the U.S. states and
territories, and other locations serviced by the U.S. postal
system. Consult the :mod:`django.contrib.localflavor` documentation
for more details.

The change to `USStateField` is technically backwards-incompatible for
users who expect this field to exclude Armed Forces locations. If you
need to support U.S. mailing addresses without Armed Forces locations,
see the list of choice tuples available in the localflavor
documentation.

The Django 1.3 roadmap
======================

Loading