抽象模型上的 ManyToManyField

Posted

技术标签:

【中文标题】抽象模型上的 ManyToManyField【英文标题】:ManyToManyField with through on an abstract model 【发布时间】:2012-02-15 16:12:52 【问题描述】:

这里有一个有趣的..我已经缩短了模型以便更容易理解..

class Participant(Person):
    passport_number = models.IntegerField(verbose_name=_('Passport Number'), db_column=u'PassportNumber')

    class Meta:
        db_table = u'Participant'

class Journey(BaseModel):
    participants = models.ManyToManyField(Participant, related_name='%(app_label)s_%(class)s_participants', through=u'ParticipantJourney')

    class Meta:
        abstract = True

class PlaneJourney(Journey):
    flight_number = models.CharField(max_length=16, verbose_name=_('Flight Number'), db_column=u'FlightNumber')

    class Meta:
        db_table = u'PlaneJourney'

class ParticipantJourney(BaseModel):
    participant = models.ForeignKey(Participant, verbose_name=_('Participant'), db_column=u'ParticipantId')

    journey_content_type = models.ForeignKey(ContentType, related_name='journey_content_type')
    journey_object_id = models.PositiveIntegerField()
    journey = generic.GenericForeignKey('journey_content_type', 'journey_object_id') # models.ForeignKey(Journey, verbose_name=_('Journey'), db_column=u'JourneyId')

    payment_content_type = models.ForeignKey(ContentType, related_name='payment_content_type')
    payment_object_id = models.PositiveIntegerField()
    payment = generic.GenericForeignKey('payment_content_type', 'payment_object_id') # models.ForeignKey(Payment, verbose_name=_('Payment'), db_column=u'PaymentId')

    class Meta:
        db_table = u'ParticipantJourney'

ParticipantJourney 模型将参与者与旅程联系起来,现在旅程是抽象的,因为它可以由任意数量的不同运输方法构成,每种运输方法都有各自的字段。我认为这个设置是正确的,但我收到以下错误消息:

错误:一个或多个模型未验证: kandersteg.planejourney: 'participants' 是通过模型 ParticipantJourney 手动定义的 m2m 关系,它没有 Participant 和 PlaneJourney 的外键

我需要保留链接表的手动定义,以便我还可以将付款链接到所述旅程,所以我真的不知道下一步该去哪里,如果有人能阐明我会非常感激!

干杯, 亚历克斯

【问题讨论】:

【参考方案1】:

Django 不将泛型外键视为 through 模型中所需的外键,目前无法在抽象基类中定义与 through 的 ManyToMany 关系。

但是,在 django (ticket #11760) 中有一个功能请求,它使您还可以在直通字段中使用 %(class)s,例如通过在Journey 模型中使用through='Pariticipant_%(class)s',然后您必须为Journey 的每个孩子手动创建直通表。但正如我所说,这只是一个开放的功能请求。

【讨论】:

【参考方案2】:

您可以尝试将 Journey 定义为非抽象的,但随后您会将数据拆分到多个表中。

我在这里发现了一些有趣的东西:https://***.com/a/3821384/1156004

【讨论】:

是的,它有效,但破坏了将它作为抽象的对象:( 添加了参与者模型,它大大缩小了(所有模型也是如此)但你明白了要点 我个人认为这可能是 django 中的一个错误,因为我查看了生成它的代码,并且它在寻找这两个时似乎没有考虑 GenericForeignKey 字段构成ManyToMany的ForeignKeys 不抽象真的有那么糟糕吗? 不,不会,但我想我会看看是否有人知道在放弃之前先让它工作的方法..

以上是关于抽象模型上的 ManyToManyField的主要内容,如果未能解决你的问题,请参考以下文章

了解抽象数据类型

MySQL 上的 @GeneratedValue 多态抽象超类

第十周软件工程学习知识总结(《数据结构与算法》)

第十周软件工程学习知识总结(《数据结构与算法》)

线性表

数据结构3