首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Django Rest框架:重复键值违反唯一约束

Django Rest框架:重复键值违反唯一约束
EN

Stack Overflow用户
提问于 2017-11-22 04:45:51
回答 3查看 3K关注 0票数 1

我对Django Rest框架有个问题。我正在开发的这个应用是“阿凡达”。用户可以更新自己的化身,然后使用我定义的路径自动保存(/ User _id/photoset_id/filename.png)。因此,我创建函数来保存如下代码:

代码语言:javascript
运行
复制
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框架创建序列化程序时,POST:

代码语言:javascript
运行
复制
class AvatarCreateUpdateSerializer(ModelSerializer):
    class Meta:
        model = Avatar
        fields = [
            'user',
            'image',
            'caption',
            'is_public',
        ]

问题是:

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

为什么我要面对这个问题,我如何解决这个问题?提前谢谢你!

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2017-11-22 04:51:29

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

在此:

代码语言:javascript
运行
复制
 super(Avatar, self).save(*args, **kwargs)

在这里:

代码语言:javascript
运行
复制
 super(Avatar, self).save(force_insert, force_update, *args, **kwargs)

正如下面的注释所述,您应该使用update_or_createget_or_create来处理这种情况。

票数 3
EN

Stack Overflow用户

发布于 2017-11-22 07:36:19

解决问题:将super(Avatar, self).save(force_insert, force_update, *args, **kwargs)转换为super(Avatar, self).save(*args, **kwargs)

票数 0
EN

Stack Overflow用户

发布于 2017-12-09 00:29:27

问题是,保存函数由rest框架传递"forced_insert=True“。当您使用相同的数据保存两次时,它试图强制插入同一主键两次。

一种解决方案是,在第一次保存之后,通过添加

代码语言:javascript
运行
复制
kwargs['force_insert'] = False

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47426979

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档