Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/320.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在Django中使用多表继承时,是否可以直接设置隐式OneToOne键?_Python_Django_Django Models_Django Orm_Django Signals - Fatal编程技术网

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序列)。看见