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.
谢谢.
除了订单问题,这是错误的:
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声明中使用引用的字符串来绕过它.
当你引用了之后定义的类时,你可以使用这个技巧:
attribute = models.ForeignKey('ClassDefinedAfterThis')
Run Code Online (Sandbox Code Playgroud)
是的,正如其他人指出的那样,顺序确实很重要。
不过,遇到这个问题几乎总是表明您做错了什么。
在这种情况下,您的声明:
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 参数。