Reputation: 5597
I am using django-rest-framework.
Is there a way to handle multiple file uploading? It seems that even the client is sending multiple files (thourgh a web browser), the MultiPartParser will only select the first file.
Upvotes: 8
Views: 7989
Reputation: 16330
I realize this is an old question, but I just spent some time banging my head against this. The issue is that Django's MultiPartParser
, which DRF uses, returns files
as a MultiValueDict
. When DRF then then adds the files back to the data that is passed to the serializer, it does so using .update()
on the data (which is an OrderedDict
) in request.Request._load_data_and_files()
. The result is that if multiple files are uploaded with the same key, only the last one survives [1] and makes it as far as the serializer.
Django's documentation recommends over-riding the .post()
method in the FormView
if using a form [2]. An alternative is to subclass the parser, and call dict()
on the files
MultiValueDict
before returning it, so that lists are returned instead of being reduced to their last value. I'm using the second option, as I'm subclassing the parser already anyway.
[1] https://docs.djangoproject.com/en/dev/_modules/django/utils/datastructures/
[2] https://docs.djangoproject.com/en/dev/topics/http/file-uploads/#uploading-multiple-files
Upvotes: 4
Reputation: 6011
You may access the file list through request.FILES.getlist('<your_payload_files_key>')
.
I got the answer from this SO answer.
Upvotes: 3
Reputation: 81
If you intend to validate multiple uploaded files, then you will have to write your own serializer for that. There is a serializers.ListField for validating lists of objects. I haven't tried this, but I believe you could implement a simple serializer like this:
class FileListSerializer ( serializers.Serializer ) :
files = serializers.ListField(
child=serializers.FileField( max_length=100000,
allow_empty_file=False,
use_url=False )
)
Then probably you could validate the files by calling the serializer from the view:
files = list( request.FILES.values() )
files_serializer = FileListSerializer( data={"files": files} )
if not file_serializer.is_valid() :
# handle error
...
Upvotes: 2