如何定义一个引用自身的Django模型?

时间:2012-11-27 21:04:17

标签: python django django-models python-2.5

我是Django的新手,目前正在编写一个应用程序,用户可以在其中输入他们对某个主题的意见。

每个意见A可能有零个或多个意见,支持A和几个(零个或多个)意见,反驳A。

我尝试为此创建一个模型并编写了一个models.py文件,如下所示:

from django.db import models

# Create your models here.
class Opinion(models.Model):
    id = models.AutoField(primary_key=True)
    contents = models.CharField(max_length=256)
    source = models.CharField(max_length=256)
    proArguments = models.ManyToManyField(Opinion, verbose_name="Pro arguments")
    contraArguments = models.ManyToManyField(Opinion, verbose_name="Contra arguments")

当我运行python manage sqlall时,我收到以下错误:

  File "D:\dev\history-site\history_site\opinions\models.py", line 4, in <module>
    class Opinion(models.Model):
  File "D:\dev\history-site\history_site\opinions\models.py", line 8, in Opinion
    proArguments = models.ManyToManyField(Opinion, verbose_name="Pro arguments")

NameError: name 'Opinion' is not defined

如何解决此错误?

3 个答案:

答案 0 :(得分:6)

来自docs of ManyToManyField

  

需要位置参数:与模型相关的类。这与ForeignKey完全相同,包括有关递归和惰性关系的所有选项。

哪个says

  

要创建递归关系 - 与自身具有多对一关系的对象 - 请使用models.ForeignKey('self')

所以:

proArguments = models.ManyToManyField("self", verbose_name="Pro arguments")
contraArguments = models.ManyToManyField("self", verbose_name="Contra arguments")

如果参数被认为是意见,我对你的数据模型有点疑惑,但这是另一回事。

答案 1 :(得分:2)

你必须使用自我。因为,你有两个m2m的自我关系,你需要添加一个related_name参数或提供symmetrical = False

class Opinion(models.Model):
    id = models.AutoField(primary_key=True)
    contents = models.CharField(max_length=256)
    source = models.CharField(max_length=256)
    proArguments = models.ManyToManyField('self', verbose_name="Pro arguments", related_name='my_proargs')
    contraArguments = models.ManyToManyField('self', verbose_name="Contra arguments", related_name='my_contraarg')

答案 2 :(得分:1)

这样做的方法是使用'self'

proArguments = models.ManyToManyField('self', verbose_name="Pro arguments")
contraArguments = models.ManyToManyField('self', verbose_name="Contra arguments")

来自django文档:

  

要创建递归关系 - 与自身具有多对一关系的对象 - 请使用models.ForeignKey('self')。