2009-12-06 51 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。