[英]How can I deserialize multiple files and form data in a single request using Django Rest Framework?
I would like to desearialize a form with some basic form data + one or more uploaded files.我想用一些基本的表单数据 + 一个或多个上传的文件去序列化一个表单。
If I send the following request (generated as Python Requests code using Postman)如果我发送以下请求(使用 Postman 生成为 Python 请求代码)
import requests
url = "http://127.0.0.1:8000/forms/test/"
payload = {
'customer_id': '123456789',
'customer_name': 'Billy Bob'}
files = [
('files', open('/C:/tmp/aaaaa.csv','rb')),
('files', open('/C:/tmp/bbbbb.csv','rb'))
]
headers= {}
response = requests.request("POST", url, headers=headers, data = payload, files = files)
print(response.text.encode('utf8'))
The code returns the following response (I hoped it would save the file instead).代码返回以下响应(我希望它会保存文件)。
{
"files": [
"This field is required."
]
}
Models楷模
from datetime import datetime
from django.db import models
class Mtfar(models.Model):
date = models.DateTimeField(auto_now_add=True)
customer_id = models.IntegerField()
customer_name = models.CharField(max_length=254)
class MtfarFile(models.Model):
file = models.FileField(blank=False, null=False)
mtfar = models.ForeignKey(Mtfar, related_name='files', on_delete=models.CASCADE)
Serializers序列化器
from rest_framework import serializers
from .models import Mtfar, MtfarFile
class MtfarFileSerializer(serializers.ModelSerializer):
class Meta:
model = MtfarFile
fields = ['file']
class MtfarSerializer(serializers.ModelSerializer):
files = MtfarFileSerializer(many=True)
class Meta:
model = Mtfar
fields = ['customer_ptid', 'customer_name', 'files']
View看法
from rest_framework.parsers import MultiPartParser, FormParser
from rest_framework.decorators import api_view, parser_classes
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import status
from .serializers import MtfarSerializer, MtfarFileSerializer
@api_view(['POST'])
@parser_classes([MultiPartParser])
def post_generic_form(request):
data = request.data
filelist = []
for f in request.FILES.getlist('files'):
filelist.append({
'file': f
})
data.setlist('files', filelist)
serializer = MtfarSerializer(data=data)
if serializer.is_valid():
serializer.save()
return Response(status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
You need to convert the QueryDict
object into a dict
to support nested serialization , because DRF parsing the QueryDict
in a different way.您需要将QueryDict
对象转换为dict
以支持嵌套序列化,因为 DRF 以不同的方式解析QueryDict
。 (Ref: get_value(self, dictionary)
method -- (DRF source code) ) (参考: get_value(self, dictionary)
方法——(DRF 源代码) )
@api_view(['POST'])
@parser_classes([MultiPartParser])
def post_generic_form(request):
dict_data = { **request.data.dict(), **{"files": [{"file": file} for file in request.FILES.getlist('files')]} }
serializer = MtfarSerializer(data=dict_data)
if serializer.is_valid():
serializer.save()
return Response(status=status.HTTP_201_CREATED)
else:
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.