USStateField (again)

8 views
Skip to first unread message

James Bennett

unread,
Aug 22, 2009, 3:21:20 AM8/22/09
to django-d...@googlegroups.com
So, the USStateField in contrib.localflavor got neutered a while back,
removing a number of items from its choices list which -- while not
actually US states -- are valid postal codes which the US Postal
Service recognizes and considers as "US" addresses. When this
happened, Django lost useful functionality: there's no longer any
field available that corresponds to what USPS will actually recognize.

And, predictably, now we've got ticket #9022 open, which started by
asking for support for US Armed Forces postal codes and has sort of
snowballed from there. The current proposal is for a
"USPostalCodeField" which corresponds to the US Postal Service's list
of postal codes:

http://www.usps.com/ncsc/lookups/abbr_state.txt

Since it's likely that any code change we end up making will be fairly
simple, I'd like to get the politics straightened out ASAP so that
Django 1.2 can have something that'll actually be useful. Based on the
various arguments up to this point, it seems like no single field is
going to make everybody happy, so here's what I'd suggest:

First, deprecate USStateField immediately. It's not and never has been
just a list of states, and the implication that the things it lists
*are* US states seems to offend some people. So kill it, already.

Then, add two new fields geared toward the actual real-world use cases:

1. A field for the 48 "contiguous" US states and the District of
Columbia. Lots of services restrict to this for shipping options.
2. A field which accepts anything the US Postal Service accepts. Call
it "USPostalCodeField" in line with the patch in #9022, or call it
"USPostalBikeshedField" for all I care. But get a field that equates
to what USPS allows.

If anybody can make a really good case for it, maybe we could do a
third field that's a restricted set of states and territories, but in
my experience places that'll ship to one overseas territory will
usually ship to them all, so I'd be inclined to leave that out.

If this sounds good, I can work up the patch and get it ready for
review Real Soon Now, and then hopefully we can put this to bed for
good.


--
"Bureaucrat Conrad, you are technically correct -- the best kind of correct."

Tim Chase

unread,
Aug 22, 2009, 7:49:09 AM8/22/09
to django-d...@googlegroups.com
James Bennett wrote:
> The current proposal is for a "USPostalCodeField" which
> corresponds to the US Postal Service's list of postal codes:
>
> http://www.usps.com/ncsc/lookups/abbr_state.txt
>
> [snip] Based on the various arguments up to this point, it

> seems like no single field is going to make everybody happy,

Internally, I've solved a similar "can't make everybody happy"
problem with a class factory function that takes the desired set
of defined data, depending on the project:

LOWER_48 = [ ... ]
US_STATES = sorted(# in shuffle AK/HI alphabetically
LOWER_48 + [
('AK', 'Alaska'),
('HI', 'Hawaii')
],
key=lambda s: s[1]
)
PROTECTORATES = [ ... ]
MILITARY_DROPS = [ ... ]
USPS_SERVICE = US_STATES + PROTECTORATES + MILITARY_DROPS

class BaseStateField(Field):
allowed_states = US_STATES
# common logic/code here

def make_state_field(desired_states=US_STATES):
class MyStateField(BaseStateField):
allowed_states = desired_states
return MyStateField

which can then be used something like

class MyModel(Model):
just_48 = make_state_field()(help="Pick a lower48 state")
all_us = make_state_field(US_STATES)(help="All the US")
my_random_whims = make_state_field(
US_STATES + PROTECTORATES)(help="Just what I wanted")

> First, deprecate USStateField immediately. It's not and never has been
> just a list of states, and the implication that the things it lists
> *are* US states seems to offend some people. So kill it, already.

With the above factory solution, one could just define it as

USStateField = make_state_field(US_STATES + WHATEVER)

to prevent breaking existing code (though I agree the name is a
bit misleading). It also allows people to easily make a custom
state-field with just the states they want:

OUR_SALES_MARKET = [ ...subset of states here... ]
SalesStates = make_state_field(OUR_SALES_MARKET)
class MyModel(Model):
sale_state = SalesStates(help="I sell stuff here...")

Just a possibility from the trenches here.

-tkc

Russell Keith-Magee

unread,
Aug 22, 2009, 9:12:12 AM8/22/09
to django-d...@googlegroups.com
On Sat, Aug 22, 2009 at 7:49 PM, Tim
Chase<django...@tim.thechases.com> wrote:
>
> James Bennett wrote:
>> The current proposal is for a "USPostalCodeField" which
>> corresponds to the US Postal Service's list of postal codes:
>>
>> http://www.usps.com/ncsc/lookups/abbr_state.txt
>>
>> [snip] Based on the various arguments up to this point, it
>> seems like no single field is going to make everybody happy,

Agreed that this particular argument is a recurring theme that we
should address.

> Internally, I've solved a similar "can't make everybody happy"
> problem with a class factory function that takes the desired set
> of defined data, depending on the project:

Given that the number of options is constrained, a fully-fledged
factory strikes me as overkill. Why not just booleans on the field
itself?

USStateField(lower_48=True, dc=True, non_contiguous=True,
protectorates=False, military_drops=True)

No need to deprecate anything - we can continue to ship USStateField
as is, just with some extra options that have default boolean values
set to reflect the currently enabled choices.

Given that US postal codes seems like a particularly common request,
there isn't much harm in including a a USPostalCodeField as a shortcut
- it's just a subclass with all the options set True.

Yours,
Russ Magee %-)

chris....@gmail.com

unread,
Aug 24, 2009, 11:08:39 PM8/24/09
to Django developers


On Aug 22, 8:12 am, Russell Keith-Magee <freakboy3...@gmail.com>
wrote:
> On Sat, Aug 22, 2009 at 7:49 PM, Tim
>
I'll toss out one idea. In Satchmo, we have an l10n application to
support this data. We use a fixture to load the following data:
- ISO2, ISO3 and ISO numeric
- Official Name, Continent and Aministrative Area (state, territory,
etc)
- List of all Admin Areas (aka states in US) with full name and
abbreviation

for most of the countries of the world.

The nice thing about this approach is that if someone wants to add an
administrative area of some sort, it can be done and if they want to
deactivate one, it's simple. I realize this may be a bit out of the
scope for this particular issue but it feels like it would be a more
robust solution and would scale nicely to other countries. This would
also be a really cool feature to have in Django as a whole. Once the
models are in place, data maintenance is pretty simple. Integrating
into the USStateField of other country fields wouldn't be too
difficult.

Anyway, let me know your thoughts. The Satchmo l10n code is BSD
licensed and I'd be willing to help if there's sufficient interest.

-Chris


Russell Keith-Magee

unread,
Aug 25, 2009, 7:24:25 AM8/25/09
to django-d...@googlegroups.com

Hi Chris,

While I can appreciate the intent of your suggestion, we've said in
the past that we don't want Django to become a repository for i18n and
l10n data. I don't see any particularly strong reason to change this
policy.

There are several reasons for this decision.

Firstly, it's a lot of data to carry around, and not every project
will need this data. It's also a huge maintenance burden for us - and
for the translators that need to inspect and potentially translate
every region name etc.

Secondly, this is one of those areas where the community can play an
important role. I'd much rather see a vibrant community of i18n/l10n
data tools than try to generate the One True Font of Regions, and ship
it with Django. Django should stick to what it is good at. Let the
community decide where the best source of i18n data is to be found.

So - Django tries to ship with a basic set of l10n data and tools that
is useful to many. It's not perfect, but it's suitable for most simple
cases. We'll try to accommodate simple configuration requests (such as
giving some flexibility for US states), but there comes a point where
we'll say no. There's a line between 'batteries included' and
'includes every battery you will ever need for every Tibetan kitchen
appliance you will ever buy' :-)

So - if you're sufficiently enthused by the l10n problem, I heartily
encourage you to split the l10n code and data out of Satchmo into a
separate project. If anyone else in the community is interested in
this problem, I encourage you to take Chris up on his invitation to
use his BSD licensed code and data. There is plenty that could be done
in the l10n space for Django, and I'm eager to see what the community
can do.

Yours,
Russ Magee %-)

Reply all
Reply to author
Forward
0 new messages