2009-05-19 16 views
29

我想將單個ForeignKey連接到兩個不同的型號。如何在Django中使用動態外鍵?

例如:

我有兩個型號命名CastsArticles,以及第三個模型,Faves,對於加入最愛無論是其他車型。我怎樣才能使ForeignKey動態?

class Articles(models.Model): 
    title = models.CharField(max_length=100) 
    body = models.TextField() 

class Casts(models.Model): 
    title = models.CharField(max_length=100) 
    body = models.TextField() 

class Faves(models.Model): 
    post = models.ForeignKey(**---CASTS-OR-ARTICLES---**) 
    user = models.ForeignKey(User,unique=True) 

這可能嗎?

回答

37

這是我如何做到這一點:

from django.contrib.contenttypes.models import ContentType 
from django.contrib.contenttypes import fields 


class Photo(models.Model): 
    picture = models.ImageField(null=True, upload_to='./images/') 
    caption = models.CharField(_("Optional caption"),max_length=100,null=True, blank=True) 

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

class Article(models.Model): 
    .... 
    images  = fields.GenericRelation(Photo) 

你會添加類似

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

到明星 和

fields.GenericRelation(Faves) 

條及鑄造

contenttypes docs

15

這是一種方法。 (請注意,該機型是獨特的,Django的自動複數化給你的。)

class Article(models.Model): 
    title = models.CharField(max_length=100) 
    body = models.TextField() 

class Cast(models.Model): 
    title = models.CharField(max_length=100) 
    body = models.TextField() 

FAVE_CHOICES = ( 
    ('A','Article'), 
    ('C','Cast'), 
) 
class Fave(models.Model): 
    type_of_fave = models.CharField(max_length=1, choices=FAVE_CHOICES) 
    cast = models.ForeignKey(Casts,null=True) 
    article= models.ForeigKey(Articles,null=True) 
    user = models.ForeignKey(User,unique=True) 

這種情況很少提出了深刻的問題。根據您的使用情況,它可能需要一些聰明的類方法。

+10

+1我認爲通用的contenttypes,正如在接受的答案中,對於那些你不瞭解關係的「可插入」模型來說更好。對於所有模型都有控制權和完整知識的情況,您的答案會更好。更好意味着在數據庫上編寫查詢和點擊更容易。 – 2009-06-24 19:39:04

相關問題