我想在 Django 中对一篇文章进行修改建模:
我在文章的 models.py 中有以下内容:
class Article(models.Model):
title = models.CharField(blank=False, max_length=80)
slug = models.SlugField(max_length=80)
def __unicode__(self):
return self.title
class ArticleRevision(models.Model):
article = models.ForeignKey(Article)
revision_nr = models.PositiveSmallIntegerField(blank=True, null=True)
body = models.TextField(blank=False)
在 artlcle 模型上,我希望有 2 个对修订的直接引用 - 一个指向已发布的修订,另一个指向正在积极编辑的修订。但是据我了解,OneToOne 和 ForeignKey 引用在模型引用的另一侧生成反向引用,所以我的问题是,如何在 Django 中创建单向一对一引用?
是否有一些特殊的咒语,或者我是否必须通过将状态包含在修订和自定义实现字段中来伪造它,要求在特定状态下进行修订?
编辑:我想,我在解释我的意图方面做得有些糟糕。让我们在更高的抽象级别上尝试一下:
我的初衷是实现一种修订版文章模型,其中每篇文章可能有多个修订版,其中一个修订版可能被“发布”,一个修订版可能被主动编辑。
这意味着文章将与修订(由 ArticleRevision 类中的 ForeignKey(Article)
引用表示)和两个单向引用具有一对多关系要修订的文章:published_revision
和 edited_revision
。
我的问题主要是,如何使用 Django 的 ORM 对其进行建模。
最佳答案
Django 产生的反向引用是程序化的,不会影响底层的数据库模式。换句话说,如果您的 Article 上有一个一对一或外键字段指向您的 Revision,那么数据库中的 Article 表将添加一列,但不会添加到 Revision 表。
因此,没有必要去掉revision对article的逆向关系。如果您真的对此有强烈的感觉,并且想在您的代码中记录从未使用过反向链接,一个相当常见的 Django 习惯用法是为字段提供一个 related_name 属性,如 _unused_1
。所以您的 Article 模型可能如下所示:
class Article(models.Model):
title = models.CharField(blank=False, max_length=80)
slug = models.SlugField(max_length=80)
revision_1 = models.OneToOneField(ArticleRevision, related_name='_unused_1')
revision_2 = models.OneToOneField(ArticleRevision, related_name='_unused_2')
def __unicode__(self):
return self.title
也就是说,一对一关系很少在应用程序中真正有用(除非您出于某种原因进行优化),我建议仔细检查您的数据库模式以确保这确实是您想要的想。在您的 ArticleRevision 上保留一个 ForeignKey 字段指向回一篇文章(因为 ArticleRevision 可能总是需要与一篇文章相关联)并向 Revision 添加另一列以指示它是否已发布可能是有意义的。
关于python - 如何在 Django 中模拟一种方式的一对一关系,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1121488/