furious-luke/django-address

Error when querying anything in Mexico

Closed this issue · 5 comments

When querying a location in Mexico, it always fails because the state code is larger than 3 digits.

E.g., when searching for "Alberto Carrera Torres, Guadalupe, Cerritos, México" it shows the error:

Invalid state code (too long): S.L.P.

I think that it is showing states abreviation instead of the 3-digit state codes. See here:
https://en.wikipedia.org/wiki/Template:Mexico_State-Abbreviation_Codes

Can't see anywhere in the response where I can get that 3-digit state code.

If you want to see the response from Google, look at this example:

https://maps.googleapis.com/maps/api/geocode/json?address=San%20Luis%20Potosi

It seems like Google is in the wrong on this one, but still doesn't work properly because of this. Maybe rising the max_length on the field will be a good temporary solution until Google gets its things together.

Here is another example:

https://maps.googleapis.com/maps/api/geocode/json?address=Chihuahua

@cesarmanzo Thank you for the report.

Related to #82. Hoping to address in 0.2.3.

Here's a sample JSON response from Google of San Luis Potosi:

[{
	"address_components": [{
		"long_name": "San Luis Potos\\u00ed",
		"short_name": "San Luis Potos\\u00ed",
		"types": ["locality", "political"]
	}, {
		"long_name": "San Luis Potosi",
		"short_name": "S.L.P.",
		"types": ["administrative_area_level_1", "political"]
	}, {
		"long_name": "Mexico",
		"short_name": "MX",
		"types": ["country", "political"]
	}],
	"formatted_address": "San Luis Potos\\u00ed, San Luis Potosi, Mexico",
	"geometry": {
		"bounds": {
			"northeast": {
				"lat": 22.2186053,
				"lng": -100.8561164
			},
			"southwest": {
				"lat": 22.0068338,
				"lng": -101.0560226
			}
		},
		"location": {
			"lat": 22.1564699,
			"lng": -100.9855409
		},
		"location_type": "APPROXIMATE",
		"viewport": {
			"northeast": {
				"lat": 22.2186053,
				"lng": -100.8561164
			},
			"southwest": {
				"lat": 22.0068338,
				"lng": -101.0560226
			}
		}
	},
	"place_id": "ChIJefusBQCiKoQRV4Lhrynu0g4",
	"types": ["locality", "political"]
}]

Questions:

Q. Why is state code limited to two characters and country code to three?
A. No obvious reason, though this was set from the initial commit. Probably author just not aware at the time that Google would return codes larger than these settings.

Q. Any tests related to this limitation?
A. Yes, test_assignment_from_dict_invalid_country_code and test_assignment_from_dict_invalid_state_code

Q. Why is are these constraints in place?
A. Presumably to help ensure these fields hold genuine abbreviations. This package is largely based on google geocode response data, and the example json in the google docs specifically has two character "short_name" fields for state and country.

Google does not appear to offer a spec for the character length for short_name fields. Though the above example has a six-character example of "S.L.P."

Q. Which field returned by G geocode is mapped to state code?
A. As per widgets.AddressWidget, state_code is mapped to administrative_area_level_1_short
Observations:

  • There may be no max limit to an admin level 1 geocode response, and it won't even necessarily match up to being a "state." In the case of this ticket's San Luis Potosí example, S.L.P. is a valid state abbreviation.

For example, the notable Building, "EME Edificio Internacional de Negocios," has the address: Av Venustiano Carranza 990, De Tequisquiapan, 78230 San Luis, S.L.P., Mexico

While initially I thought US territories could be hanbdled simply by also increasing the max amount of state code characters, as discovered in #82, US territories have a different problem. It does not appear possible to get a "valid" address for a US territory back from the google maps API geocode:

See Secret Harbour Beach Resort in St. Thomas, which should have address: 6280 Estate Nazareth, Nazareth Bay, Benner, VI 00802-1113

6280 Estate Nazareth, St Thomas 00802, U.S. Virgin Islands

This begs the question, "valid to who?" and that depends on who is shipping it, and possibly the political leanings of the person addressing it. See #82 for more discussion on this.

  • This validation check is probably most useful for helping prevent accidental mapping of say a state's actual name with the abbreviation.

Recommended changes:

  • Increase State.code max_length to 8 characters. This allows for an abbreviation like "S.L.P" Though this validation won't work if the state name is shorter than six characters.

Q. How many letters does google return at a maximum?
A. Does not appear that there is any stated maximum length

Known change needs:

  • Update model to allow longer state and country codes
  • Update tests above
  • Update AddressField validation

Notes and Follow-ons:

  • The to_python() method on AddressField does initial validation, then returns a second custom to_python() which does the bulk of dict-based address consumption validation. This address.models.to_python is where the country and state code limitations are being enforced.
  • I am not familiar enough with custom model fields, so I created #127 as an opportunity to learn more about these and make any updates necessary.
  • Reproduce failure to accept San Luis Potosí
  • Update models.py
  • Make migrations
  • Update tests as necessary

Fixed in 9cbe682 and subsequent typo-rectifying commit.