【问题标题】:Trouble saving empty Base64ImageField in Django Restframework在 Django Rest 框架中保存空的 Base64 图像字段时遇到问题
【发布时间】:2022-06-25 20:25:32
【问题描述】:

我正在使用自定义类来存储通过 API 请求传入的 base64 图像。

类如下所示:

class Base64ImageField(serializers.ImageField):

    def to_internal_value(self, data):

        if isinstance(data, six.string_types):
            if 'data:' in data and ';base64,' in data:
                header, data = data.split(';base64,')

            try:
                decoded_file = base64.b64decode(data)
            except TypeError:
                self.fail('invalid_image')

            file_name = str(uuid.uuid4())[:16] 
            file_extension = self.get_file_extension(file_name, decoded_file)
            complete_file_name = "%s.%s" % (file_name, file_extension, )
            data = ContentFile(decoded_file, name=complete_file_name)

            return super(Base64ImageField, self).to_internal_value(data)

    def get_file_extension(self, file_name, decoded_file):
        import imghdr

        extension = imghdr.what(file_name, decoded_file)
        extension = "jpg" if extension == "jpeg" else extension

        return extension

    def to_representation(self, instance):
        if instance.name:
            return(settings.BASE_URL+reverse('download', args=[instance.name]))
        else:
            return None
    

在我的 serializer.py 文件中,我是这样使用它的:

    logo = Base64ImageField(max_length=None, use_url=True, required=False, allow_null=True, allow_empty_file=True)

假设已经保存了一个徽标,现在我要删除它,我想发送一个空字符串。不幸的是,这总是以错误消息告终:

The submitted file is empty.

【问题讨论】:

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


    【解决方案1】:

    我认为您不需要创建 Base64ImageField。您只需遵循 DRY 原则。 django-extra-fields 包会为你做这件事。

    pip install django-extra-fields
    

    在 models.py 中,您只需将其定义为普通的ImageField

    logo = ImageField(max_length=None, use_url=True, required=False, allow_null=True, allow_empty_file=True)
    

    在序列化程序中,您可以定义设置Base64ImageField

    from drf_extra_fields.fields import Base64ImageField
    
    class YourModelSerializer(serializers.ModelSerializer):
        logo = Base64ImageField(required = False)
    
        class Meta:
            fields = '__all__'
            model = YourModel
            
        def create(self, validated_data):
            logo = validated_data.pop('logo')
            created_item = YourModel.objects.create(**validated_data)
            created_item.logo = logo
            created_item.save()
            return True
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-01-27
      • 2017-01-27
      • 1970-01-01
      • 1970-01-01
      • 2021-04-06
      • 2020-05-12
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多