如何使用Django BinaryField、Postgresql Bytea配合DRF实现图片入库?
问题根源
- 原代码使用
JSONParser解析请求,JSON格式本身不支持直接传输二进制数据,上传的图片无法被正常解析到请求数据中,导致存入字段为空。 - 默认的ModelSerializer未对BinaryField做文件上传适配,无法自动将上传的文件对象转换为二进制字节存储。
- 二进制文件上传需要使用
multipart/form-data格式的请求,原代码未配置对应解析器。
调整步骤
1. 修改序列化器(serializers.py)
新增文件转二进制的处理逻辑,支持直接接收上传的文件对象,可选支持base64格式的图片传输:
from rest_framework import serializers from .models import Question from django.core.files.uploadedfile import InMemoryUploadedFile import base64 class QuestionSerializer(serializers.ModelSerializer): def to_internal_value(self, data): # 处理multipart/form-data上传的文件对象 if 'question_picture' in data and isinstance(data['question_picture'], InMemoryUploadedFile): data['question_picture'] = data['question_picture'].read() # 可选:处理JSON格式提交的base64图片 # elif 'question_picture' in data and isinstance(data['question_picture'], str): # if 'base64,' in data['question_picture']: # _, base64_data = data['question_picture'].split('base64,') # data['question_picture'] = base64.b64decode(base64_data) return super().to_internal_value(data) class Meta: model = Question fields = ('question_id', 'question', 'question_picture', 'answer', 'mc_a', 'mc_b', 'mc_c')
2. 修改视图(views.py)
替换解析器为支持文件上传的类型,直接使用DRF封装好的request.data获取解析后的请求数据:
from rest_framework.decorators import api_view, parser_classes from rest_framework.parsers import MultiPartParser, FormParser from rest_framework import status from rest_framework.response import Response from .serializers import QuestionSerializer @api_view(['POST']) @parser_classes([MultiPartParser, FormParser]) def question_list(request): if request.method == 'POST': questions_serializer = QuestionSerializer(data=request.data) if questions_serializer.is_valid(): questions_serializer.save() return Response(questions_serializer.data, status=status.HTTP_201_CREATED) return Response(questions_serializer.errors, status=status.HTTP_400_BAD_REQUEST)
注意事项
- 采用
multipart/form-data上传时,前端请求头Content-Type需设为对应值,图片字段以文件类型提交即可。 - 若不需要接口返回图片二进制内容,可将
question_picture从序列化器的fields中移除,减少响应体积。 - 生产环境更推荐将图片存储在对象存储服务或本地文件系统,数据库仅存储图片访问路径,降低数据库存储压力。
内容的提问来源于stack exchange,提问作者Aras121
相关产品推荐
相关产品推荐

