如何在创建照片时创建迷你照片?

how can i create mini photo while creating photo?

我在 django 上有一个照片上传服务。 当我添加一张照片时,我希望它再添加一张拆分为 50% 的照片。 如果我将它放在我的照片保存服务的 pre_save 中,它找不到照片(因为它实际上不在服务器上)如果我将它添加到 post_save,它会进入循环并添加无限

当我添加照片时(邮递员等)如何一次保存一张小照片?

这是我的模型

class UserPhoto(General, Status):
    user = models.ForeignKey(UserBase, on_delete=models.CASCADE, verbose_name="User Id", related_name='UserPhoto_user',
                             null=True, blank=True)
    link = models.ImageField(blank=True, null=True)
    order = models.IntegerField(null=True, blank=True)
    mini_link = models.ImageField(upload_to='mini_photos', blank=True, null=True)

    class Meta:
        db_table = 'user_photos'

我的观点

class UserPhoto(APIView):
    def get_object(self, pk):
        try:
            return Photo.objects.get(user__user__pk=pk)
        except Exception as e:
            return e

    def get(self, request):
        try:
            photo = self.get_object(request.user.pk)
            serializer = UserPhotoSerializer(photo)
            return Response(serializer.data)
        except Exception as e:
            print(e)

    def post(self, request):
        serializer = UserPhotoSerializer(data=request.data, context={'request': request})
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data, status=status.HTTP_201_CREATED)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def put(self, request):
        photo = self.get_object(request.user.pk)
        serializer = UserPhotoSerializer(photo, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

我的序列化程序

class UserPhotoSerializer(serializers.ModelSerializer):
    class Meta:
        model = UserPhoto
        fields = '__all__'

    def create(self, validated_data):
        validated_data["user"] = self.context['request'].user.User_userbase
        return UserPhoto.objects.create(**validated_data)

我的信号

@receiver(pre_save, sender=UserPhoto)
    def create_mini_photo(sender, instance=None, created=False, **kwargs):
    blob = BytesIO()
    path = instance.link.path
    image = Image.open(path)
    width, height = image.size
    resized_image = image.resize((int(width / 2), int(height / 2)))
    resized_image = resized_image.convert('RGB')
    resized_image.save(blob, 'JPEG')
    instance.mini_link.save(str(instance.link), File(blob), save=False) 

据我了解,用户照片模型中存在状态,当您添加新照片时,您将停用旧数据并创建新记录。

因此,您可以先更新序列化器上的create方法如下;

    def create(self, validated_data):
       validated_data["user"] = self.context['request'].user.User_userbase
       validated_data["status"] = "Active"
       photos = UserPhoto.objects.filter(user=self.context['request'].user.User_userbase, status="Active")
       if len(photos) > 0:
          for photo_obj in photos:
               photo_obj.status = "Passive"
               photo_obj.save()
       return UserPhoto.objects.create(**validated_data)

进行此更新后,您可以使用信号中的 created 参数使代码仅适用于新记录。这样,上传真实照片后,将创建一个新的录音,信号内部将起作用,而在录制缩小50%的照片时,将不起作用,因为没有新的录音。这里的重点是您使用 post_save 因为必须保存照片。例子;

@receiver(post_save, sender=UserPhoto)
def create_mini_photo(sender, instance=None, created=False, **kwargs):
    if created:
       blob = BytesIO()
       path = instance.link.path
       image = Image.open(path)
       width, height = image.size
       resized_image = image.resize((int(width / 2), int(height / 2)))
       resized_image = resized_image.convert('RGB')
       resized_image.save(blob, 'JPEG')
       instance.mini_link.save(str(instance.link), File(blob), save=False)