简体   繁体   English

为什么我的django模型会抛出错误?

[英]Why is my django model throwing an error?

I'm putting together a model for a blog app. 我正在为一个博客应用程序组建一个模型。

Here's the model: 这是模型:

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

I added the blog package to settings.py. 我将博客包添加到了settings.py中。 Then I ran python manage.py sql blog . 然后我运行了python manage.py sql blog I got the following errors: 我收到以下错误:

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

I don't understand why Post is not defined because I am defining it in the models.py file. 我不明白为什么Post没有定义,因为我在models.py文件中定义它。 What am I missing? 我错过了什么?

Problem 问题

When you are defining Tag class, Post class is not yet defined. 在定义Tag类时,尚未定义Post类。 Because you are referring to it, you get NameError exception. 因为您指的是它,所以会出现NameError异常。

Solution

Thus, change this line: 因此,改变这一行:

posts = models.ManyToManyField(Post)

into this line: 进入这一行:

posts = models.ManyToManyField('Post')

Explanation 说明

The documentation gives you walkaround: 该文档为您提供了解决方法:

If you need to create a relationship on a model that has not yet been defined, you can use the name of the model, rather than the model object itself: 如果需要在尚未定义的模型上创建关系,可以使用模型的名称,而不是模型对象本身:

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

Alternative solution 替代方案

You can also omit definition of posts in Tag class (the line " posts = models.ManyToManyField(Post) ") and just provide the appropriate name for reverse relation in Post model. 您还可以省略Tag类中的posts定义(“ posts = models.ManyToManyField(Post) ”行),并在Post模型中为反向关系提供相应的名称。 Django will know what to do with it. Django将知道如何处理它。 Just replace this line: 只需替换此行:

tags = models.ManyToManyField(Tag)

with this line: 用这一行:

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

To learn more, read about related_name argument when defining relations ( ForeignKey and ManyToManyField ). 要了解更多信息,请在定义关系时阅读related_name参数ForeignKeyManyToManyField )。

As answered before , you have are referencing a model (Post) before you've actually defined it -- definition order in a Python file is significant. 如前所述,在实际定义模型之前 ,您已经引用了模型(Post) - Python文件中的定义顺序非常重要。

To get around the problem, let Django resolve that name rather than Python, by enclosing it with single-quotes: 为了解决这个问题,让Django解析该名称而不是Python,用单引号括起来:

posts = models.ManyToManyField('Post')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM