声明的顺序在models.py(Django/Python)中是否重要?

ric*_*ick 5 django django-models

我在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)
Run Code Online (Sandbox Code Playgroud)

当我这样做时,我得到:

NameError: name 'City' is not defined
Run Code Online (Sandbox Code Playgroud)

这是因为申报的顺序很重要吗?如果是这样,我怎么能这样做,因为无论我采用哪种方式,看起来我都会得到一个NameError.

谢谢.

Car*_*yer 6

除了订单问题,这是错误的:

cities = City.objects.filter(zip=self).distinct()
Run Code Online (Sandbox Code Playgroud)

它不在方法中,因此"self"也将是未定义的.它只在类创建时执行一次(即首次导入模块时),因此创建的属性将是一个类属性,并且对所有实例具有相同的值.您可能正在寻找的是:

@property
def cities(self):
  return City.objects.filter(zip=self).distinct()
Run Code Online (Sandbox Code Playgroud)

因为这是在方法内部,在访问之前不会执行,所以排序问题将不再是问题.正如ozan指出的那样,这是Django反向关系已经免费提供的重复:

a_zip_code.city_set.all()
Run Code Online (Sandbox Code Playgroud)

你可以使用related_name来调用它你喜欢的:

zip = models.ManyToManyField(ZipCode, related_name='cities')
...
a_zip_code.cities.all()
Run Code Online (Sandbox Code Playgroud)

因此,我认为您最初询问的订购问题甚至与您的情况无关.如果是,其他人已经指出在ForeignKey和ManyToManyField声明中使用引用的字符串来绕过它.


Ale*_* S. 5

当你引用了之后定义的类时,你可以使用这个技巧:

attribute = models.ForeignKey('ClassDefinedAfterThis')
Run Code Online (Sandbox Code Playgroud)


oza*_*zan 4

是的,正如其他人指出的那样,顺序确实很重要。

不过,遇到这个问题几乎总是表明您做错了什么。

在这种情况下,您的声明:

cities = City.objects.filter(zip=self).distinct()
Run Code Online (Sandbox Code Playgroud)

...既多余又不好的做法。您可以通过在视图中引用邮政编码的 city_set(即不在模型中!)来查找与邮政编码相关的城市。因此,如果 zip 是 ZipCode 的实例,您将执行以下操作:

cities = zip.city_set.all()
Run Code Online (Sandbox Code Playgroud)

如果您确实想将其称为“城市”而不是“city_set”,您可以在 m2m 声明中使用 related_name 参数。