我有以下型号:
class Work_Music(MPTTModel, Work):
name = models.CharField(max_length=10, null=True, blank=True)
class Opera(models.Model):
work = models.OneToOneField(Work_Music, verbose_name=_('work_music'), related_name='opera', on_delete=models.PROTECT)
cast = models.ManyToManyField('Cast', through='WorkCast')
source_writer = models.ForeignKey(Person, verbose_name=_('author'), null=True, blank=True, on_delete=models.PROTECT)
numbering = models.CharField(max_length=8000, null=True, blank=True)
work_type = models.CharField(max_length=8000, null=True, blank=True)
class Cast(models.Model):
name = models.CharField(max_length=100, null=True, blank=True)
def __str__(self):
return self.name
class WorkCast(models.Model):
work = models.ForeignKey(Work_Music, verbose_name=_('work'), related_name='workcast', null=True, blank=True, on_delete=models.PROTECT)
cast = models.ManyToManyField(Cast, verbose_name=_('cast'), related_name='workcast', blank=True)
def __str__(self):
return "%s" % (
", ".join(character.name for character in self.cast.all())
)
当前数据结构为:
WorkCast
|-----> Opera
|-----> Opera cast member #1
Opera cast member #2
Opera cast member #3
我现在想为每个铸件附加一个唱歌范围,以完成这项特定的工作。像这样的东西:
WorkCast
|-----> (ForeignKey) Opera
|-----> (Many-to-many) Opera cast member #1, lowest note: c, highest note: A#
Opera cast member #2, lowest note: b, highest note: D
Opera cast member #3, lowest note: a, highest note: E
如何附加:
lowest_note = models.CharField(max_length=10, null=True, blank=True)
highest_note = models.CharField(max_length=10, null=True, blank=True)
该特定作品的每个演员?
答案 0 :(得分:0)
我认为您正在寻找的是through table
。进一步了解here
您的代码如下所示。
class WorkCast(models.Model):
work = models.ForeignKey(Work_Music, verbose_name=_('work'), related_name='workcast', null=True, blank=True, on_delete=models.PROTECT)
cast = models.ManyToManyField(Cast, verbose_name=_('cast'), related_name='workcast', blank=True, through='SingRange')
def __str__(self):
return "%s" % (
", ".join(character.name for character in self.cast.all())
)
class SingRange(models.Model):
lowest_note = models.CharField(max_length=10, null=True, blank=True)
highest_note = models.CharField(max_length=10, null=True, blank=True)
答案 1 :(得分:0)
建模有点“ 奇数”。通常,人们希望您在ManyToManyField
模型上定义WorkMusic
,并将WorkCast
用作两者之间的“直通”模型。您可以使用through=…
parameter [Django-doc]进行指定。喜欢:
class WorkMusic(MPTTModel, Work):
name = models.CharField(max_length=10, null=True, blank=True)
cast = models.ManyToManyField('Cast', through='WorkCast')
class Cast(models.Model):
name = models.CharField(max_length=100, null=True, blank=True)
def __str__(self):
return self.name
class WorkCast(models.Model):
work = models.ForeignKey(
WorkMusic,
verbose_name=_('work'),
related_name='workcast',
null=True,
blank=True,
on_delete=models.PROTECT
)
cast = models.ForeignKey(
Cast,
verbose_name=_('cast'),
related_name='workcast',
blank=True,
on_delete=models.PROTECT
)
lowest_note = models.CharField(max_length=10, null=True, blank=True)
highest_note = models.CharField(max_length=10, null=True, blank=True)
在这里,我们将为每个与{em> one WorkCast
对象和 one WorkMusic
相关的Cast
对象进行编码反对多余的字段。 WorkMusic
对象可以具有个零,一个或多个相关的WorkCast
对象,因此与零个,一个或多个 { {1}}个对象。
注意:通常是Django模型,就像Python中的所有类在 PerlCase 中都有一个名称,而不是 snake_case 一样,因此它应该是:
Cast
而不是。WorkMusic
答案 2 :(得分:0)
您可以为m2m关系创建自己的模型,并将所有必需的字段添加到该模型。您可以在ManyToManyField
中通过参数指定使用此模型。
文档:https://docs.djangoproject.com/en/3.0/topics/db/models/#extra-fields-on-many-to-many-relationships