Question

I have a Django app that has a series of zip code tagged posts. I'd like to create a page that shows all posts by state but am not sure how to go about it. I do have a ZipCode table, but my Post.zipcode field is not related to it (mostly because it is user entered, and allows zips that are not in the DB or from outside the US).

My relevant models:

class Post(models.Model):
    body = models.TextField()
    zipcode = models.CharField(max_length=5)

class ZipCode(models.Model):
    zipcode = models.CharField(max_length=5)
    city = models.CharField(max_length=64)
    statecode = models.CharField(max_length=2)
    statename = models.CharField(max_length=32)
    latitude = models.FloatField()
    longitude = models.FloatField()

In my Django view I'd love to take the "state" parameter that is passed in from my url pattern and do something like this:

def posts_by_state(request, state):
    posts = Post.objects.filter(zipcode__statecode=state)
    ...

Unfortunately, my Post.zipcode field is not a foreign key to ZipCode so I get this error if I try:

FieldError at /post/state/VT/
Join on field 'zipcode' not permitted.

Anyone have a hint as to how I should construct a queryset that pulls all posts together for a requested state? Thank you in advance.

Was it helpful?

Solution

I'd suggest updating Post.zipcode to be a ForeignKey to ZipCode. If you can't you could do the lookup like this:

zipcodes = [zip_code.zipcode for zip_code in ZipCode.objects.filter(statecode=state)]
posts = Post.objects.filter(zipcode__in=zipcodes)

On a side note, ZipCode doesn't seem like the right name for that model. Perhaps Location would be better.

OTHER TIPS

Fairly easy solution in the end. What I did was add a new foreign key field to Post called location so Post now looks like this:

class Post(models.Model):
   body = models.TextField()
   zipcode = models.CharField(max_length=5)
   location = models.ForeignKey(ZipCode, null=True, blank=True, default=None)

When I create new Posts, I check to see if the inputted zip string matches a record in the ZipCode database, and if it does I create the location FK. This then allows me to do this in my view:

def posts_by_state(request, state):
   posts = Post.objects.filter(location__statecode=state)
   ...

Thank you Seth and sdolan for your help!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top