Django Rest Framework:重复键值违反唯一约束
Posted
技术标签:
【中文标题】Django Rest Framework:重复键值违反唯一约束【英文标题】:Django Rest Framework: Duplicate key value violates unique constraint 【发布时间】: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)
为什么我会遇到这个问题,我该如何解决这个问题?提前谢谢!
【问题讨论】:
【参考方案1】:您在模型的基类上调用了两次save()
方法:
这里:
super(Avatar, self).save(*args, **kwargs)
这里:
super(Avatar, self).save(force_insert, force_update, *args, **kwargs)
正如下面的评论所说,您应该使用update_or_create
或get_or_create
来处理这种情况。
【讨论】:
而且你基本上也可以使用更新而不是像那样保存它:***.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 使用更新方法,因此不会尝试两次创建相同的主键。
【讨论】:
以上是关于Django Rest Framework:重复键值违反唯一约束的主要内容,如果未能解决你的问题,请参考以下文章
如何处理 django-rest-framework 中 url 模式中的外键关系
django rest framework 外键序列化方法与问题总结
如何避免 Django Forms 和 Django Rest Framework Serializers 中的代码重复?
在序列化程序中编辑外键字段 - Django Rest Framework