如何在Django中使用动态外键?

44 投票
2 回答
20112 浏览
提问于 2025-04-15 11:41

我想把一个 ForeignKey 连接到两个不同的模型上。

举个例子:

我有两个模型,分别叫 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)

这样做可能吗?

2 个回答

23

这里有一种方法。(注意,模型是单数形式,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)

这通常不会造成太大的问题。根据你的使用情况,可能需要一些巧妙的类方法。

66

这是我怎么做的:

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')

到收藏夹(Faves)

还有

    fields.GenericRelation(Faves)

到文章(Article)和播客(Cast)

关于内容类型的文档

撰写回答