【问题标题】:Define ForeignKey to a model before defining that model在定义模型之前为模型定义 ForeignKey
【发布时间】:2019-01-09 08:17:35
【问题描述】:

因此,我需要在定义模型之前为模型创建外键。考虑以下模型:

class Question(models.Model):
    """Model for question."""

    question_text = models.TextField(blank=True, null=True)
    answer = models.ForeignKey(Option, on_delete=models.PROTECT)  # Can't do this


class Option(models.Model):
    """Model for options of a question."""

    question = models.ForeignKey(Question, on_delete=models.CASCADE)
    text = models.CharField(max_length=127)

如您所见,我有一个模型来保存问题(文本及其答案)。此外,我还有另一种模型来保存一个与问题相关联的选项。这样我就可以为问题的选项创建变量编号,其中一个是正确的。但我无法将正确的选项链接到模型 Question,因为需要先声明模型 Question 才能将每个 Option 链接到 Question
有什么方法可以实现吗?

更新

经过一番思考,我想出了我可以使用的模型结构,我需要一个模型来回答。

class Question(models.Model):
    """Model for question."""
    ...


class Option(models.Model):
    """Model for options of a question."""
    ...

class Answer(models.Model):
    """Model for answers."""

    question = models.OneToOneField(Question, on_delete=models.CASCADE)
    answer = models.ForeignKey(Option, on_delete=models.PROTECT)

但问题仍然是我如何在定义模型之前引用它(如果可能的话)。

【问题讨论】:

标签: python django python-3.x django-models


【解决方案1】:

这就是我将如何重写您的代码示例:

class Question(models.Model):
    """Model for question."""

    question_text = models.TextField(blank=True, null=True)
    answer = models.ForeignKey('Option', on_delete=models.PROTECT)  # Can't do this


class Option(models.Model):
    """Model for options of a question."""

    question = models.ForeignKey('Question', on_delete=models.CASCADE)
    text = models.CharField(max_length=127)

请注意传递给ForeignKey 的第一个参数(粗体)。它是一个带有模型名称的字符串。

如果您查看foreignkey 的官方 Django 文档,您会看到那里对此进行了解释:

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

我个人认为这是一个很好的做法,并在所有模型类中始终如一地使用它,无论它们的定义顺序如何。好处是重构代码时不必考虑顺序。

此外,您还可以参考其他应用中的模型:


class Foo(models.Model):
    bar = models.ForeignKey('baz.SomeModel', on_delete=models.DO_NOTHING)

没有像这样显式导入模块:

from baz.models import SomeModel

【讨论】:

  • 兄弟,你是个救命稻草 ?,这么简单的解决方案,我疯了想弄清楚如何做到这一点。
  • 很高兴它有帮助。我忘了说它叫lazy relationship,以防你想回到这个问题。
猜你喜欢
  • 1970-01-01
  • 2014-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-30
  • 2012-06-24
  • 2011-02-08
  • 1970-01-01
相关资源
最近更新 更多