在Django Rest Framework中接收Base64编码图像并保存到ImageField中

时间:2013-05-13 13:24:36

标签: django json django-models django-rest-framework

我需要从应用程序接收图像,我能想到的最好方法是将其发送到Base64编码的JSON数组中。图像非常小,所以我不在乎额外的开销。

我有一个模特:

class Observation(models.Model):    
    ...
    sonogram_image = models.ImageField(upload_to=sonogram_dir)

它的序列化器:

class ObsvSerializerNoDetect(serializers.HyperlinkedModelSerializer):

    class Meta:
        model = Observation

我应该在哪里放置代码来解码图像?

3 个答案:

答案 0 :(得分:8)

以下是如何在基于Django(drf的)API端的post请求中处理Base64编码的图像文件,并将其保存为ImageField。

假设你有一个模型如下:

Class MyImageModel(models.Model):
      image = models.ImageField(upload_to = 'geo_entity_pic')
      data=model.CharField()

所以对应的序列化器如下:

 from drf_extra_fields.fields import Base64ImageField

 Class MyImageModelSerializer(serializers.ModelSerializers):
      image=Base64ImageField()
      class meta:
         model=MyImageModel
         fields= ('data','image')
      def create(self, validated_data):
        image=validated_data.pop('image')
        data=validated_data.pop('data')
       return MyImageModel.objects.create(data=data,image=image)

相应的View可以如下:

elif request.method == 'POST':
    serializer = MyImageModelSerializer(data=request.data)
    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data, status=201)
    return Response(serializer.errors, status=400)

注意在Serializer中我使用了模块django-extra-field中提供的Base64ImageField的实现

要安装此模块,请运行命令

pip install django-extra-fields

导入相同的内容并完成!

发送(通过post方法)您的图像作为JSON对象中的Base64编码字符串以及您拥有的任何其他数据。

答案 1 :(得分:1)

根据您的使用情况,可能有两个最佳位置:

    在您的序列化程序中
  1. ,您可以使用validate_Xtransform_X方法覆盖您的字段(请参阅validation docs)以及此处双向转换。

  2. 如果您需要更频繁地使用此功能,请
  3. 编写您自己的custom field。您只需要在to_nativefrom_native中定义转化在两个方向上的运行方式。也许扩展原始DRF ImageField以保持PIL的图像数据验证。

  4. 更新DRF3:

    transform_X方法由to_representation()替换。请参阅removal-of-transform_field_nameOverriding serialization and deserialization behavior

    另请参阅此DRF Base64ImageFieldMixin示例。

答案 2 :(得分:1)

试试 django extra fields 。使用Base64ImageField作为序列化器字段,当然假设您在模型中使用了ImageField。