代码之家  ›  专栏  ›  技术社区  ›  Roland Tepp

如何在Django中建模单向一对一关系

  •  4
  • Roland Tepp  · 技术社区  · 17 年前

    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)
    

    是否有一些特殊的咒语,或者我必须通过将状态包含在请求特定状态下的修订的字段的修订和自定义实现中来伪造它?

    编辑: 我想,我在解释我的意图方面做得有点糟糕。让我们在更高的抽象级别上尝试一下:

    这意味着文章将与修订有一对多的关系(以 ForeignKey(Article) 类)和两个从文章到修订的单向引用: published_revision edited_revision .

    2 回复  |  直到 15 年前
        1
  •  5
  •   mmalone    17 年前

    Django生成的反向引用是程序化的,不会影响底层数据库模式。换句话说,如果您的文章上有一个一对一或外键字段指向您的修订版,则数据库中的文章表中会添加一列,但修订版表中不会添加一列。

    因此,没有必要从文章的修订中删除相反的关系。如果你真的对此有强烈的感受,并想在代码中记录从未使用过反向链接,Django中一个相当常见的习惯用法是给字段一个related_name属性,比如 _unused_1 。因此,您的文章模型可能如下所示:

    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
    

    也就是说,一对一的关系在应用程序中实际上很有用(除非你出于某种原因进行优化),我建议仔细检查你的数据库模式,以确保这是你真正想要的。在Article Revision上保留一个ForeignKey字段,指向一篇文章(因为Article Revisions可能总是需要与一篇文章相关联),并在Revision中添加另一列,表明它是否已发布,这可能是有意义的。

        2
  •  4
  •   markijbema    14 年前
    推荐文章