2009-05-19 13 views
29

ForeignKeyを2つの異なるモデルに接続したいとします。例えばDjangoで動的な外部キーを使用するには?

私は他のモデルのいずれかをお気に入りへの追加のための2つのCastsArticlesという名前のモデル、および第3のモデル、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) 

を記事にして

0を投じます

15

ここにアプローチがあります。 (Djangoが自動的にpluralizes、モデルは単数形であることに注意してください。)

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は、受け入れられた答えのように、関係について何も知らない「差し替え可能な」モデルに適していると思います。あなたの答えは、あなたがすべてのモデルのコントロールと完全な知識を持っている状況に適しています。データベースへのクエリの書き込みが簡単になり、ヒット率が低下することを意味します。 –

+2

キャストと記事FKフィールドargsで "null = True"を忘れました。各Faveインスタンスは、type_of_faveフィールドの設定に対応する1つのFKフィールドをNoneに設定しないためです – Geradeausanwalt

関連する問題