Django:与Contenttypes的通用一对多关系

时间:2009-12-06 12:15:34

标签: django generics

我正在努力使以下适合Django ORM。拥有Publish模型,用于管理不同类型内容(其他模型)的发布。这样我就可以轻松地Publish.objects.all()按日期排序。我制作了一个通用模型如下:

class Publish(models.Model):
    """ Intermediary model for displaying and managing different types of content """
    status = models.IntegerField(_('status'), choices=STATUS_CHOICES, default=1)
    publish = models.DateTimeField(_('publish'), default=datetime.datetime.now)

    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = generic.GenericForeignKey('content_type', 'object_id')

问题在于我想将此附加到不同的模型。这必须是OneToMany关系。因为一篇文章只能有一个出版日期。据我所知,一般关系是ManyToMany关系。

我尝试在admin.py中限制max_num中的extraGenericTabularInline,但这不是一个很好的解决方案。有谁知道如何将发布模型附加到几个不同的模型,使其成为一个必需的,一对多的关系?许多是Publish模型,一个是ex。一篇文章。

3 个答案:

答案 0 :(得分:8)

您的假设不正确 - 通用外键是一对多,而不是多对多。您可以看到您的模型具有content_objectobject_id字段 - 即此Publish实例链接到单个目标对象,尽管该对象可以有许多Publish实例。

您真正想要的是OneToOne模型。您可以使用您拥有的模型模拟它,您可以简单地限制发布对象的创建,以便每个目标对象只能有一个。您可以在Meta子类中的unique_togethercontent_type上设置object_id来完成此操作。

class Publish(models.Model):
    ... fields ...

    class Meta:
        unique_together('content_type', 'object_id')

您可能想要考虑的另一个选项是尝试多表模型继承,而不是使用泛型关系,其中每个对象都继承自Publish。

答案 1 :(得分:0)

我会写一个OneToOneGenericForeignKey,我不知道。

或者,如果文章(或任何其他对象)只能发布一次,他们可以参考发布模型。

但是,我不这样做,因为我有意义地发布多次(类别,网站)的内容,所以我只是通过max_num / field / save / manager /中放置限制并保持我的选项打开为未来。

答案 2 :(得分:0)

在你的问题中并不完全清楚(其他人似乎总结得不同),但在我看来你并不是要求OneToOne,你要求OneToMany方向相反(发布实例可以有多篇文章,但不是相反的方式)。在这种情况下,您将完全放弃GenericForeignKey,并确保所有内容模型都具有正常的ForeignKey发布。如果你愿意的话,你可以使用抽象模型继承来干掉它。