Does order of declaration matter in models.py (Django / Python)?
Question: I have something like this in models.py

    
    
    class ZipCode(models.Model):
        zip = models.CharField(max_length=20)
        cities = City.objects.filter(zip=self).distinct()
    
    class City(models.Model):
        name = models.CharField(max_length=50)
        slug = models.CharField(max_length=50)
        state = models.ForeignKey(State)
        zip = models.ManyToManyField(ZipCode)
    

When I do this I get:

    
    
    NameError: name 'City' is not defined
    

Is this because the order of declaration matters? And if so, how can I do
this, because either way I arrange this, it looks like I'm going to get a
NameError.

Thanks.


Answer: Apart from order issues, this is wrong:

    
    
    cities = City.objects.filter(zip=self).distinct()
    

It is not inside a method, so "self" will also be undefined. It is executed
only once, at class-creation time (i.e. when the module is first imported), so
the attribute created would be a class attribute and have the same value for
all instances. What you might be looking for is this:

    
    
    @property
    def cities(self):
      return City.objects.filter(zip=self).distinct()
    

Because this is inside a method, which is not executed until it's accessed,
ordering issues will no longer be a problem. As ozan points out, this is a
duplication of what Django reverse relations already give you for free:

    
    
    a_zip_code.city_set.all()
    

And you can use related_name to call it what you like:

    
    
    zip = models.ManyToManyField(ZipCode, related_name='cities')
    ...
    a_zip_code.cities.all()
    

So I don't think the ordering issue you originally asked about is even
relevant to your situation. When it is, others have already pointed out using
quoted strings in ForeignKey and ManyToManyField declarations to get around
it.

