Python 如何在Django中创建多对一关系?

Python 如何在Django中创建多对一关系?,python,django,database,relationship,many-to-one,Python,Django,Database,Relationship,Many To One,如问题所述,如何在django模型中创建多对一关系 基本上,我有两个模型:文章和漫画,我想有一个评论模型,它与文章和漫画都有关系,但不是两者都有关系。 因此,如果评论对象与文章对象有关系,那么它就不会与漫画对象有关系 我目前正在按以下方式进行操作,但不起作用: class Article(models.Model): #other fields class Comic(models.Model): #other fields class Comment(models.Model)

如问题所述,如何在django模型中创建多对一关系

基本上,我有两个模型:文章和漫画,我想有一个评论模型,它与文章和漫画都有关系,但不是两者都有关系。 因此,如果评论对象与文章对象有关系,那么它就不会与漫画对象有关系

我目前正在按以下方式进行操作,但不起作用:

class Article(models.Model):
    #other fields
class Comic(models.Model):
    #other fields
class Comment(models.Model):
    article = models.ForeignKey(Article)
    comic = models.ForeignKey(Comic)

我非常感谢您的帮助。

这很棘手。我认为有两种方法可以对其进行建模

使用当前的方式,可以在应用程序中强制实施唯一性约束

class Comment(models.Model):
    article = models.ForeignKey(Article)
    comic = models.ForeignKey(Comic)

    def save(self, *args, **kwargs):
        # assert that there is either comic OR article but not both
        super(Comment, self).save(*args, **kwargs)
通过这种方式,如果您添加了另一个要引用的模型,会发生什么??您必须在save方法中手动添加新类型的条件并执行迁移

Django提供了GenericForeignKey字段,允许您从
注释中引用任何模型

这将允许您创建一个从
Comment
到Article或Comic的通用引用,并且由于它只是一个字段,因此默认情况下是互斥的。我发现查询和使用
GenericeForeignKey
s很尴尬;但它们仍然是一个选项,对于您的用例来说可能很好


另一个强大的选择,(我最喜欢的)可能是创建一个多态模型,这也是相互排斥的

每个
注释
都可以使用模型继承引用一段通用的
内容
。(我没有测试以下内容,因此可能无法复制/粘贴)

这是建模
注释
与任何
内容
之间关系的一种强大方法。这确实增加了额外的查询开销,并且应该保证对您的用例进行审计

InheritanceManager
是django model utils软件包提供的一个实用程序,非常轻量级。我已经在生产环境中使用过它,只要您了解在使用它建模数据时无意中听到的额外查询,它就是性能良好的

文档中解释了查询开销


如果您认为将来会添加额外的
内容
子类,那么这可能是一种可扩展的关系建模方法,并在过滤方面提供了比
GenericForeignKey
s更大的灵活性。

好吧,您可以在注释模型中添加另一个字段。像

class Comment(models.Model):
    article = models.ForeignKey(Article, null = True)
    comic = models.ForeignKey(Comic, null = True)
    assigned = models.BooleanField(initial=False)

创建注释对象后,将article或comic指向另一个对象,并使assigned=True。

是否出现错误?你能发布完整的追踪吗?嗯,我知道这是一个复杂的问题。谢谢你的解决方案,我会尝试一下。
class Comment(models.Model):
    article = models.ForeignKey(Article, null = True)
    comic = models.ForeignKey(Comic, null = True)
    assigned = models.BooleanField(initial=False)