【问题标题】:How to define a Django model with a reference to itself?如何定义一个引用自身的 Django 模型?
【发布时间】:2012-11-27 21:04:16
【问题描述】:

我是 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

我该如何解决这个错误?

【问题讨论】:

    标签: python django django-models python-2.5


    【解决方案1】:

    来自docs of ManyToManyField

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

    哪个says

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

    所以:

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

    如果参数也被视为意见,我有点想知道您的数据模型,但这是另一回事。

    【讨论】:

    • 我认为论点就是观点,但这只是我的观点。
    • 由于该论点是您的观点,我认为我认为这显然不是论点。但是我们不要有这个论点,因为它会变得非常固执。
    • @Thomas 有没有办法告诉 Django 可能有没有参数的意见(当两个集合都为空时)?我将字段定义修改为proArguments = models.ManyToManyField('self', verbose_name="Pro arguments", related_name='proargs', null='true', blank='true'),但是当我在管理员中创建Opinion 的新实例时,有一个赞成论点和一个反对论点(尽管我没有输入它们)。
    【解决方案2】:

    你必须使用 self.既然,你有两个 m2m 自我关系,你需要添加一个 related_name 参数或提供symmetric=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')
    

    【讨论】:

      【解决方案3】:

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

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

      来自 django 文档:

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

      【讨论】:

        猜你喜欢
        • 2011-06-22
        • 2020-03-16
        • 1970-01-01
        • 2021-01-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多