Django,REST:将文本或图像文件序列化为通过HTTP以JSON形式发布

2 投票
2 回答
6363 浏览
提问于 2025-04-18 15:16

运行环境: Windows 7, Python 3.3, Django 1.6

背景: 我正在用Django和REST框架创建一个应用,这个应用可以接收HTTP的'POST'请求,里面包含了对象的JSON描述,然后根据这些'POST'请求在SQL数据库中创建记录。大部分数据库记录的字段都是整数,比如numOfTests,或者是字符类型的字段,比如result。这些字段通过REST框架的serializers.py文件被反序列化到Django中,简单来说,就是把普通的JSON字符串转换成Django中的对象,然后Django再用合适的命令把它们保存到SQL数据库里。不过在每个表记录中,我们还需要存储一个文本文件和一个截图,我还没弄明白怎么通过HTTP和JSON发送这些文件。

我之前看过如何通过Django的命令行上传图片文件,这里有一个以前的问题提到过。但在我的情况下,所有的数据录入都是由远程计算机完成的,都是通过HTTP请求的主体中的JSON来发送的。

问题: 有没有办法把图片文件或文本文件序列化,这样我们办公室的各种远程计算机就可以通过JSON把它们发送到Django服务器?

注意: 这些HTTP的POST请求将由脚本发送,具体来说,每当一个测试完成时(用Python),它会向我们的服务器网址发送一个HTTP的POST请求,里面包含关于测试完成的详细信息。所以没有人会手动进入命令行去保存图片到Django中。

2 个回答

1

我想这可能是最简单、最干净的方法来实现这个功能。

假设你有一个模型,内容如下:

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)

对应的视图可以这样写:

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)

注意,在序列化器中,我使用了模块 django-extra-field 提供的 Base64ImageField 实现。

要安装这个模块,你可以运行以下命令:

pip install pip install django-extra-fields

导入这个模块就完成了!

通过 POST 方法发送你的图片,作为一个 Base64 编码的字符串放在 JSON 对象里,连同你其他的数据一起发送。

3

是的,你可以用base64来编码图片,然后直接在请求中发送,但这有点像是变通的做法。如果你把base64直接存到数据库里,最后数据库会变得非常庞大,这样不好。

这里有一段代码示例,它在传输过程中使用了base64,但最终是保存为ImageField:

http://www.snip2code.com/Snippet/93486/Django-rest-framework---Base64-image-fie

我看到的唯一问题是,这样会让使用Firebug(或类似工具)进行调试变得更加困难,因为传输的数据量会变得很大。

撰写回答