抽象模型中的ManyToManyField及其through选项
这里有个有趣的问题.. 我把模型简化了一下,方便理解..
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手动定义的多对多关系,但它没有指向Participant和PlaneJourney的外键
我需要保留这个手动定义的链接表,因为我还想把支付信息和旅程关联起来,所以我不知道接下来该怎么做。如果有人能帮我解答一下,我将非常感激!
谢谢, Alex
2 个回答
0
你可以尝试把Journey定义为一个具体的类,而不是抽象类,但这样的话数据就会分散在多个表格里。
我在这里发现了一些有趣的内容: https://stackoverflow.com/a/3821384/1156004
3
Django不把通用外键当作通过模型中必需的外键,目前也没有办法在抽象基类中定义一个带有通过模型的多对多关系。
不过,Django中有一个功能请求(ticket #11760),希望能让你在通过字段中使用%(class)s
,比如在Journey
模型中使用through='Pariticipant_%(class)s'
。这样的话,你需要为每个Journey
的子类手动创建通过表。但正如我所说,这个功能请求目前还只是个开放的提议。