Python 在Django中使用多表继承时,是否可以直接设置隐式OneToOne键?
我试图通过多表继承来扩展库模型,结果是:Python 在Django中使用多表继承时,是否可以直接设置隐式OneToOne键?,python,django,django-models,django-orm,django-signals,Python,Django,Django Models,Django Orm,Django Signals,我试图通过多表继承来扩展库模型,结果是: class CompetitionMedia(InstagramMedia): visible = models.BooleanField(default=True) most_creative = models.BooleanField(default=False) @receiver(post_save, sender=InstagramMedia, dispatch_uid='create_competition_media')
class CompetitionMedia(InstagramMedia):
visible = models.BooleanField(default=True)
most_creative = models.BooleanField(default=False)
@receiver(post_save, sender=InstagramMedia, dispatch_uid='create_competition_media')
def create_competition_media(sender, instance, created, **kwargs):
competition_media = CompetitionMedia()
competition_media.instagrammedia = instance
competition_media.save() # fails
@receiver(post_save, sender=InstagramMedia, dispatch_uid='create_competition_media2')
def create_competition_media2(sender, instance, created, **kwargs):
CompetitionMedia.objects.create(instagrammedia=instance) # Fails
有可能做到这一点吗?据我所知,您希望得到如下内容:
class CompetitionMedia(models.Model):
instagrammedia = models.OneToOneField(InstagramMedia, primary_key=True)
visible = models.BooleanField(default=True)
most_creative = models.BooleanField(default=False)
@receiver(post_save, sender=InstagramMedia, dispatch_uid='create_competition_media2')
def create_competition_media(sender, instance, created, **kwargs):
if created:
CompetitionMedia.objects.create(instagrammedia=instance)
据我所知,你想得到这样的东西:
class CompetitionMedia(models.Model):
instagrammedia = models.OneToOneField(InstagramMedia, primary_key=True)
visible = models.BooleanField(default=True)
most_creative = models.BooleanField(default=False)
@receiver(post_save, sender=InstagramMedia, dispatch_uid='create_competition_media2')
def create_competition_media(sender, instance, created, **kwargs):
if created:
CompetitionMedia.objects.create(instagrammedia=instance)
很明显,我应该设置
parent\u ptr
,比如:
@receiver(post_save, sender=InstagramMedia, dispatch_uid='create_competition_media')
def create_competition_media2(sender, instance, created, **kwargs):
if created:
CompetitionMedia.objects.create(instagrammedia_ptr=instance)
但是,如果先创建并保存父项,然后尝试创建子项,则即使在子项中未设置的字段上,子项也会覆盖父项。正如和中所描述的,我会避免它,只是因为它不是很明显会发生
如果有人真的想走这条路,你需要做:
@receiver(post_save, sender=InstagramMedia, dispatch_uid='create_competition_media')
def create_competition_media2(sender, instance, created, **kwargs):
if created:
CompetitionMedia.objects.create(instagrammedia_ptr=instance)
instance.save() # This should re-save the parent values.
更好的是:
@receiver(post_save, sender=InstagramMedia, dispatch_uid='create_competition_media')
def create_competition_media2(sender, instance, created, **kwargs):
if created:
CompetitionMedia.objects.create(instagrammedia_ptr=instance,
**instance.__dict__)
很明显,我应该设置
parent\u ptr
,比如:
@receiver(post_save, sender=InstagramMedia, dispatch_uid='create_competition_media')
def create_competition_media2(sender, instance, created, **kwargs):
if created:
CompetitionMedia.objects.create(instagrammedia_ptr=instance)
但是,如果先创建并保存父项,然后尝试创建子项,则即使在子项中未设置的字段上,子项也会覆盖父项。正如和中所描述的,我会避免它,只是因为它不是很明显会发生
如果有人真的想走这条路,你需要做:
@receiver(post_save, sender=InstagramMedia, dispatch_uid='create_competition_media')
def create_competition_media2(sender, instance, created, **kwargs):
if created:
CompetitionMedia.objects.create(instagrammedia_ptr=instance)
instance.save() # This should re-save the parent values.
更好的是:
@receiver(post_save, sender=InstagramMedia, dispatch_uid='create_competition_media')
def create_competition_media2(sender, instance, created, **kwargs):
if created:
CompetitionMedia.objects.create(instagrammedia_ptr=instance,
**instance.__dict__)
仅当创建新实例时才需要保存。顺便说一句,你有什么错误?@Rohan我在简化示例时排除了它,但你是对的。我得到的错误是,
instagrammedia
字段不存在。只有在创建新实例时才需要保存。顺便说一句,你有什么错误?@Rohan我在简化示例时排除了它,但你是对的。我得到的错误是,instagrammedia
字段不存在。虽然这是实现相同目标的一种方法,但我实际上只想知道多表继承而不是组合是否可行。这并不是您想要的,但可能是一个可接受的解决方案(我项目中的一个示例)字体但据我所知,通常你想要的是不可能的。继承将创建一个单独的表,如果它是proxy=True
或abstract=True
模型,则不执行任何操作。显而易见的方法是覆盖模型的元类。虽然这是实现相同目标的一种方法,但我实际上只想知道多表继承而不是组合是否可行。这并不是您想要的,但可能是一个可接受的解决方案(我项目中的一个示例):但据我所知,通常你想要的是不可能的。继承将创建一个单独的表,如果它是proxy=True
或abstract=True
模型,则不执行任何操作。最明显的方法是重写模型的元类。当您使用现有的基类实例创建派生类实例时,您还需要在派生类中复制基类的属性。这个问题对@Rohan I喜欢这个答案很有帮助,它比重新保存父项更干净(尽管仍然很奇怪),命中率低1 db。从字典中删除PK或使用force_insert
(尽管后者可能会干扰PK序列)。请参见,当使用现有基类实例创建派生类实例时,还需要在派生类中复制基类的属性。这个问题对@Rohan I喜欢这个答案很有帮助,它比重新保存父项更干净(尽管仍然很奇怪),命中率低1 db。从字典中删除PK或使用force_insert
(尽管后者可能会干扰PK序列)。看见