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

Ana*_*kin 35 python django foreign-keys

我想连接一个ForeignKey到两个不同的模型.

例如:

我有一个名为两款车型Casts,并Articles和第三个模型,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)
Run Code Online (Sandbox Code Playgroud)

这可能吗?

Vik*_*ica 46

我是这样做的:

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)
Run Code Online (Sandbox Code Playgroud)

你会添加类似的东西

    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    content_object = fields.GenericForeignKey('content_type', 'object_id')
Run Code Online (Sandbox Code Playgroud)

收藏和

    fields.GenericRelation(Faves)
Run Code Online (Sandbox Code Playgroud)

文章和演员

contenttypes docs


S.L*_*ott 18

这是一种方法.(注意,模型是单数,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)
Run Code Online (Sandbox Code Playgroud)

这很少会带来深刻的问题.它可能需要一些聪明的类方法,具体取决于您的用例.

  • +1我认为通用内容类型,如在已接受的答案中,对于"可插拔"模型更好,在这些模型中您不了解关系.对于您拥有所有模型的控制和完整知识的情况,您的答案会更好.更好意味着更容易编写查询并减少对数据库的命中. (14认同)
  • 您忘记了演员和文章FK字段args中的"null = True",因为每个Fave实例只会将一个FK字段设置为None,这对应于type_of_fave字段中的设置 (2认同)