问题
I need to model a postal address that can have multiline street address, the city, the state (province), and the postal code. the country is omitted.
I need to preserve line breaks in the street addresses but still be able to search the addresses.
I see two ways to do it:
class Address(models.Model):
street = models.ForeignKey('StreetAddress')
city = models.TextField()
province = models.TextField()
code = models.TextField()<br>
class StreetAddress(models.Model):
line_number = models.IntegerField()
text = models.TextField()
or this one which stores the street address in a single text field but uses special separator characters to encode line breaks:
class Address(models.Model):
street = models.TextField()
city = models.TextField()
province = models.TextField()
code = models.TextField()
what is the best way to do it in terms of code readability and efficiency (or their balance)?
回答1:
Unless the majority of your addresses have multi-line street parts (and have many lines), I'd go for the latter, storing it all in a single field, and not bothering with an additional model. If most of your multi-line addresses are only two lines, consider creating a street and street2 field in your Address model (you could choose more descriptive names for these two "street" fields). The first would store the first street line, and the second field would store all additional lines (separated by newlines). I would think when searching addresses, you'd most often search on the address line that contains the street number, so maybe in your program logic you'd ensure that the street number line was always stored in the first "street" field, which you could then add an index on in your database.
On the other hand, if most of your addresses will have multi-line street parts, and have more than two lines, then it makes sense to create that second model.
If you don't know in advance, and don't mind potentially "migrating" in the future, go for the simpler model. Otherwise, go for your two-model design.
回答2:
Here's how I model addresses for the US. You could also store a 10 digit zip code (XXXXX-XXXX) if you needed.
You may also consider adding a point field, or a poly field from geodjango depending on what you're using the addresses for.
from django.contrib.gis.db import models
from django.utils.translation import ugettext as _
from django.contrib.localflavor.us.models import USStateField
class UsLocation(models.Model):
address_1 = models.CharField(_("address"), max_length=128)
address_2 = models.CharField(_("address cont'd"), max_length=128, blank=True)
city = models.CharField(_("city"), max_length=64, default="Zanesville")
state = USStateField(_("state"), default="OH")
zip_code = models.CharField(_("zip code"), max_length=5, default="43701")
回答3:
I have some questions about your address data:
- Is the data already verified down to the delivery point?
- If so, do you have a high percentage that still have more than one delivery line (street field)?
Most delivery addresses only have a single line. Many people erroneously place secondary information (unit number) on the second delivery line. This goes against USPS standards (see USPS publication 28). So, I recommend that you get your address data verified using a CASS-Certified vender so you know that the addresses you are dealing with are real and standardized. Then you will probably be in a better position to analyze your data and make a decision about how to store it. My guess is that after performing address verification on your database you won't have very many (if any) address with more than a single delivery line. You'd have to decide at that point whether it's worth it to have a separate field for it or keep it in a single field that's delimited with a line break.
Full disclosure: I'm a software developer for SmartyStreets, an address verification company and CASS-Certified vender.
来源:https://stackoverflow.com/questions/7700487/how-to-model-a-postal-address