2009-12-06 39 views
3

我试图在Django ORM中进行以下操作。有一个Publish模型,管理不同类型的内容(其他模型)的发布。这样我就可以轻松完成Publish.objects.all()并按日期排列。我做了一个通用模型,如下所示:Django:与Contenttypes的通用一对多关系

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关系。

我试图限制在GenericTabularInlinemax_numextra在admin.py,但是这是不是一个伟大的工作解决方案。有谁知道如何将发布模型附加到几个不同的模型,使其成为必需的一对多关系?很多人都是发布模式,一个是为前者。一篇文章。

回答

7

你的假设是不正确的 - 通用外键是一对多,不是多对多。你可以看到你的模型有content_objectobject_id字段 - 即这个发布实例链接到单个目标对象,尽管该对象可以有很多发布实例。

你真正想要的,它似乎是一个OneToOne模型。您可以使用您拥有的模型来模拟该模型,只需限制发布对象的创建,以便每个目标对象只能有一个。您可以通过在Meta子类中的content_typeobject_id上设置unique_together来完成此操作。

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

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

你可能要考虑的另一个选择是不是使用一般的关系,尽量多表模型继承,其中每个对象从发布继承。

+0

谢谢你的回答。我的最终解决方案是我确实在模型级别添加了“unique_together”的验证。 比我更改了管理视图来编辑必须链接到“发布”的模型,并在该视图内添加了“发布”模型表单。现在看起来''Publish''是模型的一部分。 – wunki 2009-12-07 20:21:21

0

我会写一个OneToOneGenericForeignKey,我不知道任何。或者,如果文章(或任何其他对象)只能发布一次,他们可以参考发布模型。

但是,我不会那么做,因为我有多次发布的东西(类别,网站)是有意义的,所以我只是通过max_num/field/save/manager/whatever来限制,并让我的选项为未来开放。

0

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