2009-05-19 24 views
29

İki farklı modele tek bir ForeignKey bağlamak istiyorum. ÖrneğinDjango'da dinamik yabancı anahtar nasıl kullanılır?

:

diğer modelden herhangi favorilere iki Casts ve Articles adlı modelini ve üçüncü modeli, Faves var. ForeignKey dinamik nasıl yapabilirim?

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) 

Bu mümkün mü? İşte

cevap

37

olduğunu ben bunu nasıl:

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) 

ekleyebilir bir şey Faves için

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

ve

fields.GenericRelation(Faves) 

maddesi ve Cast

gibi

contenttypes docs

15

İşte bir yaklaşım. (Django sizin için otomatik olarak pluralizes, modeller tekil olduğunu unutmayın.)

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) 

Bu nadiren derin problemler ortaya çıkarır. Kullanım durumlarınıza bağlı olarak bazı akıllı sınıf yöntemleri gerekebilir.

+10

+1 Genel olarak, kabul edilen cevaplarda olduğu gibi, genel içerik türleri, ilişkilerle ilgili hiçbir şey bilmediğiniz "takılabilir" modeller için daha iyidir. Cevabınız, tüm modellerin kontrol ve tam bilgisine sahip olduğunuz durumlar için daha iyidir. Daha iyi, veritabanında sorgu yazmak ve daha az isabet yazmak daha kolay demektir. –

+2

Tüm Fave örneği yalnızca bir FK alanını yalnızca Type_of_fave alanındaki ayara karşılık gelen None olarak ayarlamayacağından, yayın ve makale FK alanı arşivi için "null = True" öğesini unutmuşsunuzdur. – Geradeausanwalt