【问题标题】:Why is my django model throwing an error?为什么我的 django 模型会抛出错误?
【发布时间】:2012-10-08 00:52:33
【问题描述】:

我正在为博客应用程序构建一个模型。

这是模型:

from django.db import models

class Tag(models.Model):
    keyword = models.CharField(max_length=256)
    posts = models.ManyToManyField(Post)

    def __unicode__(self):
        return self.keyword

class Post(models.Model):
    title = models.CharField(max_length=512)
    image = models.ImageField
    body = models.TextField()
    visible = models.BooleanField()
    date_created = models.DateTimeField(auto_now_add=True)
    date_updated = models.DateTimeField(auto_now=True)
    tags = models.ManyToManyField(Tag)

    def __unicode__(self):
        return self.title

我将博客包添加到 settings.py。然后我跑了python manage.py sql blog。我收到以下错误:

 File "/pathto/blog/models.py", line 5, in Tag
    posts = models.ManyToManyField(Post)
NameError: name 'Post' is not defined

我不明白为什么没有定义 Post,因为我在 models.py 文件中定义了它。我错过了什么?

【问题讨论】:

    标签: python django-models


    【解决方案1】:

    问题

    当您定义Tag 类时,Post 类尚未定义。因为你指的是它,所以你得到NameError 异常。

    解决方案

    因此,改变这一行:

    posts = models.ManyToManyField(Post)
    

    进入这一行:

    posts = models.ManyToManyField('Post')
    

    说明

    The documentation 为您提供漫游:

    如果您需要在尚未定义的模型上创建关系,您可以使用模型的名称,而不是模型对象本身:

    class Car(models.Model):
        manufacturer = models.ForeignKey('Manufacturer')
        # ...
    
    class Manufacturer(models.Model):
        # ...
    

    替代解决方案

    您也可以在Tag 类中省略posts 的定义(“posts = models.ManyToManyField(Post)”行),而只需在Post 模型中为反向关系提供适当的名称。 Django 会知道如何处理它。只需替换这一行:

    tags = models.ManyToManyField(Tag)
    

    用这一行:

    tags = models.ManyToManyField(Tag, related_name='posts')
    

    要了解更多信息,请阅读 related_name argument when defining relationsForeignKeyManyToManyField)。

    【讨论】:

    • 什么?当 Post 是一个字符串时,它怎么知道要查找它?
    • @quakkels:当它是一个字符串时,查找由 Django 在需要时处理。您可以将其视为“惰性”外键(意思是:直到需要时才评估)。当您使用 Post 作为参考时,您遇到了 Python 代码中的基本错误:未定义名为 Post 的变量。
    【解决方案2】:

    正如before 的回答,您在实际定义模型(帖子)之前就引用了它——Python 文件中的定义顺序很重要。

    为了解决这个问题,让 Django 解析该名称而不是 Python,方法是用单引号括起来:

    posts = models.ManyToManyField('Post')

    【讨论】:

      猜你喜欢
      • 2017-04-01
      • 2021-07-24
      • 2019-09-24
      • 2016-01-04
      • 2017-12-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多