使用 ListField 序列化多个 InMemoryUploadedFile :Django REST Framework
Serialize multiple InMemoryUploadedFile using ListField : Django REST Framework
如何序列化多个 InMemoryUploadedFile
using serializers.ListField()
??
代码片段
#views.py
@api_view(['POST', 'GET'])
def create_post(request):
if request.method == 'POST':
altered_request_data = request.data.copy()
in_memory_upload_files_list = [value for value in request.FILES.values()]
altered_request_data['files'] = in_memory_upload_files_list
serializer = PostSerializer(data=altered_request_data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(data=serializer.data, status=201)
else:
qs = Post.objects.all()
serializer = PostSerializer(qs, many=True)
return Response(serializer.data)
#serilizers.py
class PostSerializer(serializers.ModelSerializer):
files = serializers.ListField(child=serializers.FileField(), write_only=True)
class Meta:
fields = '__all__'
model = Post
当前响应
{
"files": {
"0": [
"The submitted data was not a file. Check the encoding type on the form."
]
}
}
您应该使用 FILES
的 getlist
方法,它会给您文件列表。
in_memory_upload_files_list = request.FILES.getlist('<file field name>')
altered_request_data['files'] = in_memory_upload_files_list
serializer = PostSerializer(data=altered_request_data)
此处<file field name>
将是您上传文件的名称文件字段。
https://docs.djangoproject.com/en/2.2/ref/request-response/#django.http.QueryDict.getlist
问题出在这一行,
altered_request_data['files'] = in_memory_upload_files_list
这里的altered_request_data
是一个QueryDict
object, so if we assign anything to it will call the __setitem__()
方法
In [6]: from django.http import QueryDict
In [7]: qd = QueryDict('a=1&a=2&c=3',mutable=True)
In [8]: qd
Out[8]: <QueryDict: {'a': ['1', '2'], 'c': ['3']}>
In [9]: my_list = [i for i in range(10)]
In [10]: my_list
Out[10]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [11]: qd['foo']=my_list
In [12]: qd
Out[12]: <QueryDict: {'a': ['1', '2'], 'c': ['3'], <b>'foo': [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]</b>}>
看到了吗? qd['foo']
成为列表列表。也就是说,分配给 QueryDict
的任何内容都将存储在 list
对象中。
那么,解决方案是什么?
QueryDict
class 有一个方法 QueryDict.setlist
可以完成工作
In [15]: qd__new
Out[15]:
In [16]: qd__new = QueryDict('a=1&a=2&c=3',mutable=True)
In [17]: qd__new
Out[17]: <QueryDict: {'a': ['1', '2'], 'c': ['3']}>
In [18]: my_list
Out[18]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [19]: qd__new.setlist('foo_new',my_list)
In [20]: qd__new
Out[20]: <QueryDict: {'a': ['1', '2'], 'c': ['3'], <b>'foo_new': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]</b>}>
代码片段
views.py
@api_view(['POST', 'GET'])
def create_post(request):
if request.method == 'POST':
altered_request_data = request.data.copy()
in_memory_upload_files_list = [value for value in request.FILES.dict().values()]
<b>altered_request_data.setlist('files', in_memory_upload_files_list)</b>
serializer = PostSerializer(data=altered_request_data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(data=serializer.data, status=201)
else:
qs = Post.objects.all()
serializer = PostSerializer(qs, many=True)
return Response(serializer.data)
如何序列化多个 InMemoryUploadedFile
using serializers.ListField()
??
代码片段
#views.py
@api_view(['POST', 'GET'])
def create_post(request):
if request.method == 'POST':
altered_request_data = request.data.copy()
in_memory_upload_files_list = [value for value in request.FILES.values()]
altered_request_data['files'] = in_memory_upload_files_list
serializer = PostSerializer(data=altered_request_data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(data=serializer.data, status=201)
else:
qs = Post.objects.all()
serializer = PostSerializer(qs, many=True)
return Response(serializer.data)
#serilizers.py
class PostSerializer(serializers.ModelSerializer):
files = serializers.ListField(child=serializers.FileField(), write_only=True)
class Meta:
fields = '__all__'
model = Post
当前响应
{
"files": {
"0": [
"The submitted data was not a file. Check the encoding type on the form."
]
}
}
您应该使用 FILES
的 getlist
方法,它会给您文件列表。
in_memory_upload_files_list = request.FILES.getlist('<file field name>')
altered_request_data['files'] = in_memory_upload_files_list
serializer = PostSerializer(data=altered_request_data)
此处<file field name>
将是您上传文件的名称文件字段。
https://docs.djangoproject.com/en/2.2/ref/request-response/#django.http.QueryDict.getlist
问题出在这一行,
altered_request_data['files'] = in_memory_upload_files_list
这里的altered_request_data
是一个QueryDict
object, so if we assign anything to it will call the __setitem__()
方法
In [6]: from django.http import QueryDict
In [7]: qd = QueryDict('a=1&a=2&c=3',mutable=True)
In [8]: qd
Out[8]: <QueryDict: {'a': ['1', '2'], 'c': ['3']}>
In [9]: my_list = [i for i in range(10)]
In [10]: my_list
Out[10]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [11]: qd['foo']=my_list
In [12]: qd
Out[12]: <QueryDict: {'a': ['1', '2'], 'c': ['3'], <b>'foo': [[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]]</b>}>
看到了吗? qd['foo']
成为列表列表。也就是说,分配给 QueryDict
的任何内容都将存储在 list
对象中。
那么,解决方案是什么?
QueryDict
class 有一个方法 QueryDict.setlist
可以完成工作
In [15]: qd__new
Out[15]:
In [16]: qd__new = QueryDict('a=1&a=2&c=3',mutable=True)
In [17]: qd__new
Out[17]: <QueryDict: {'a': ['1', '2'], 'c': ['3']}>
In [18]: my_list
Out[18]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
In [19]: qd__new.setlist('foo_new',my_list)
In [20]: qd__new
Out[20]: <QueryDict: {'a': ['1', '2'], 'c': ['3'], <b>'foo_new': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]</b>}>
代码片段
views.py
@api_view(['POST', 'GET'])
def create_post(request):
if request.method == 'POST':
altered_request_data = request.data.copy()
in_memory_upload_files_list = [value for value in request.FILES.dict().values()]
<b>altered_request_data.setlist('files', in_memory_upload_files_list)</b>
serializer = PostSerializer(data=altered_request_data)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(data=serializer.data, status=201)
else:
qs = Post.objects.all()
serializer = PostSerializer(qs, many=True)
return Response(serializer.data)