python - Django:错误:“重复键值违反唯一约束”
问题描述
为我的网站创建新对象时,我必须使用 s3 保存图像。
我有一个代码来保存我在模型的保存方法中使用的图像。
当我使用 django 管理面板时,我可以轻松地创建我的对象而不会出现任何错误。
当我在不添加图像的情况下发送数据时,它也能正常工作。
但是当我尝试通过我的视图创建我的对象时,我收到了这个错误:Error: 'duplicate key value violates unique constraint « store_shop_pkey »' DETAIL: key (id)=(37) already exists
我认为在我的序列化程序的创建方法中,我尝试保存我的对象两次:一次用于图像,一次用于对象的其余键。
我不知道如何解决这个问题。
它适用于 PUT 方法。
这是我的代码:
模型.py:
class Shop(models.Model):
name = models.CharField(max_length=255)
category = models.ForeignKey(ShopCategory, on_delete=models.SET_NULL, null=True, blank=True)
description = models.TextField(blank=True, null=True)
path = models.CharField(max_length=255, unique=True, null=True, blank=True) # Set a null and blank = True for serializer
mustBeLogged = models.BooleanField(default=False)
deliveries = models.FloatField(validators=[MinValueValidator(0),], default=7)
message = models.TextField(null=True, blank=True)
banner = models.ImageField(null=True, blank=True)
def save(self, *args, **kwargs):
try:
"""If we want to update"""
this = Shop.objects.get(id=self.id)
if self.banner:
image_resize(self.banner, 300, 300)
if this.banner != self.banner:
this.banner.delete(save=False)
else:
this.banner.delete(save=False)
except:
"""If we want to create a shop"""
if self.banner:
image_resize(self.banner, 300, 300)
super().save(*args, **kwargs)
def delete(self):
self.banner.delete(save=False)
super().delete()
def __str__(self):
return self.name
实用程序.py:
def image_resize(image, width, height):
# Open the image using Pillow
img = Image.open(image)
# check if either the width or height is greater than the max
if img.width > width or img.height > height:
output_size = (width, height)
# Create a new resized “thumbnail” version of the image with Pillow
img.thumbnail(output_size)
# Find the file name of the image
img_filename = Path(image.file.name).name
# Spilt the filename on “.” to get the file extension only
img_suffix = Path(image.file.name).name.split(".")[-1]
# Use the file extension to determine the file type from the image_types dictionary
img_format = image_types[img_suffix]
# Save the resized image into the buffer, noting the correct file type
buffer = BytesIO()
img.save(buffer, format=img_format)
# Wrap the buffer in File object
file_object = File(buffer)
# Save the new resized file as usual, which will save to S3 using django-storages
image.save(img_filename, file_object)
视图.py:
class ShopList(ShopListView):
"""Create shop"""
def post(self, request):
"""For admin to create shop"""
serializer = MakeShopSerializer(data=request.data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors)
序列化程序.py:
class MakeShopSerializer(serializers.ModelSerializer):
class Meta:
model = Shop
fields = '__all__'
def create(self, validated_data):
# validated_data.pop('path')
path = validated_data["name"].replace(" ", "-").lower()
path = unidecode.unidecode(path)
unique = False
while unique == False:
if len(Shop.objects.filter(path=path)) == 0:
unique = True
else:
# Generate a random string
char = "abcdefghijklmnopqrstuvwxyz"
path += "-{}".format("".join(random.sample(char, 5)))
shop = Shop.objects.create(**validated_data, path=path)
shop.save()
return shop
def update(self, instance, validated_data):
#You will have path in validated_data
#And you may have to check if the values are null
return super(MakeShopSerializer, self).update(instance, validated_data)
最后,这是我发送的数据:
预先感谢您的帮助
解决方案
下一行可能是主键有问题:
shop = Shop.objects.create(**validated_data, path=path)
您可以尝试将每个属性一个一个地放置,如下所示:
shop = Shop.objects.create(
name=validated_data['name'],
category=validated_data['category'],
...
path=path)
如果它没有解决您的问题,请从终端发布更多关于您的错误的信息
推荐阅读
- javafx - 如何创建响应式盒子设计
- android - PagingLibrary 未加载更多数据
- php - 盖伊。HTTPS 重定向
- ssl-certificate - NativeScript 'tns run android' 抛出无法找到请求目标的有效认证路径
- intellij-idea - 集成终端在idea 2018中消失了
- stored-procedures - SQL Server 2017 存储过程需要声明表变量,但它已经存在
- php - 502 网关故障(1-C Bitrix)
- python - 如何计算列表中的重复列表?Python
- swift - iOS非阻塞状态栏
- java - 使用 Process 从 Java 代码执行 Java 程序