【问题标题】:Django Rest Framework: Duplicate key value violates unique constraintDjango Rest Framework:重复键值违反唯一约束
【发布时间】:2017-11-22 04:45:51
【问题描述】:

我对 Django Rest 框架有疑问。我正在构建的这个应用程序是 Avatar。用户可以更新他/她自己的头像,然后用我定义的路径(/users_id/photoset_id/filename.png)自动保存头像。所以我制作了这样的代码保存功能:

def avatar_file_path(instance, filename):
    ext = filename.split('.')[-1]
    filename = '%s.%s' % (instance.id, ext)
    return "users/%s/avatar/%s_%s" %(instance.user.id, instance.photoset.id, filename)

class Avatar(models.Model):
    user = models.ForeignKey(User, related_name='avatar_set', null=True)
    photoset = models.ForeignKey(PhotoSet, null=True, blank=True)
    primary = models.BooleanField(default=True)
    caption = models.TextField(blank=True, null=True)
    image = models.ImageField(max_length=1024, upload_to=avatar_file_path)
    is_public = models.BooleanField(_('is public'), default=True, help_text=_('Public photographs will be displayed in the default views.'))
    date_uploaded = models.DateTimeField(default=datetime.datetime.now)

    def save(self, force_insert=False, force_update=False, *args, **kwargs):
        # Make one primary Avatar
        if self.primary:
            avatars = Avatar.objects.filter(user=self.user, primary=True).exclude(id=self.id)
            avatars.update(primary=False)
        # Set default photoset
        if self.photoset is None:
            if not PhotoSet.objects.filter(user=self.user, photoset_type=3).exists():
                PhotoSet.objects.create(user=self.user, photoset_type=3, title='Profile Pictures')
                self.photoset = PhotoSet.objects.get(user=self.user, photoset_type=3)
            if PhotoSet.objects.filter(user=self.user, photoset_type=3).exists():
                self.photoset = PhotoSet.objects.get(user=self.user, photoset_type=3)
        # Model Save override 
        if self.id is None:
            saved_image = self.image
            self.image = None
            super(Avatar, self).save(*args, **kwargs)
            self.image = saved_image
        super(Avatar, self).save(force_insert, force_update, *args, **kwargs)

当我使用 Django Rest Framework 创建序列化程序 POST 时:

class AvatarCreateUpdateSerializer(ModelSerializer):
    class Meta:
        model = Avatar
        fields = [
            'user',
            'image',
            'caption',
            'is_public',
        ]

出现问题:

在线错误日志跟踪: super(Avatar, self).save(force_insert, force_update, *args, **kwargs)

为什么我会遇到这个问题,我该如何解决这个问题?提前谢谢!

【问题讨论】:

    标签: python django django-models django-rest-framework


    【解决方案1】:

    您在模型的基类上调用了两次save() 方法:

    这里:

     super(Avatar, self).save(*args, **kwargs)
    

    这里:

     super(Avatar, self).save(force_insert, force_update, *args, **kwargs)
    

    正如下面的评论所说,您应该使用update_or_createget_or_create 来处理这种情况。

    【讨论】:

    • 而且你基本上也可以使用更新而不是像那样保存它:stackoverflow.com/questions/6382806/…
    • 当我删除这一行时:super(Avatar, self).save(*args, **kwargs)。我无法在路径中使用 avatar_id 预先保存。文件路径来:users/1/avatar/1_None.jpg 代替 users/1/avatar/1_9.jpg (9 是 avatar_id)
    • @Clement 你能帮我把这条线改成get_or_create吗?兄弟
    • 我建议您先自己尝试一下。编程最好是边做边学。尝试后,如果您仍然卡住,请发布一个新问题,我很乐意为您提供帮助。祝你好运!
    • 感谢@ClémentDenoix。我会试试的
    【解决方案2】:

    已修复问题:将 super(Avatar, self).save(force_insert, force_update, *args, **kwargs) 更改为 super(Avatar, self).save(*args, **kwargs)

    【讨论】:

      【解决方案3】:

      问题是保存函数被其余框架传递“forced_insert=True”。当您使用相同的数据保存两次时,它会尝试强制插入相同的主键两次。

      一个解决方案是在第一次保存后将强制插入重置为 添加

      kwargs['force_insert'] = False
      

      在第二次保存之前。这将允许 Django 使用更新方法,因此不会尝试两次创建相同的主键。

      【讨论】:

        猜你喜欢
        • 2016-06-12
        • 2016-11-27
        • 2018-03-14
        • 2012-12-31
        • 1970-01-01
        • 2011-06-26
        • 2012-06-20
        • 2019-09-22
        相关资源
        最近更新 更多