Django REST Framework + Django REST Swagger + ImageField
I got this working by making a couple of changes to your code.
First, in models.py
, change ImageField
name to file
and use relative path to upload folder. When you upload file as binary stream, it's available in request.data
dictionary under file key (request.data.get('file')
), so the cleanest option is to map it to the model field with the same name.
from django.utils import timezonefrom django.db import modelsclass MyModel(models.Model): file = models.ImageField(upload_to=u'photos') is_active = models.BooleanField(default=False) created_at = models.DateTimeField(default=timezone.now) def __unicode__(self): return u"photo {0}".format(self.file.url)
In serializer.py
, rename source field to file:
class MyModelSerializer(serializers.ModelSerializer): class Meta: model = MyModel fields = ('id', 'file', 'created_at')
In views.py, don't call super, but call create():
from rest_framework import genericsfrom rest_framework.parsers import FileUploadParserfrom .serializer import MyModelSerializerclass MyModelView(generics.CreateAPIView): serializer_class = MyModelSerializer parser_classes = (FileUploadParser,) def post(self, request, *args, **kwargs): """ Create a MyModel --- parameters: - name: file description: file required: True type: file responseMessages: - code: 201 message: Created """ return self.create(request, *args, **kwargs)
I've used Postman Chrome extension to test this. I've uploaded images as binaries and I've manually set two headers:
Content-Disposition: attachment; filename=upload.jpgContent-Type: */*
This is the final solution I came up with:
from rest_framework import genericsfrom rest_framework.parsers import FormParser, MultiPartParserfrom .serializer import MyModelSerializerclass MyModelView(generics.CreateAPIView): serializer_class = MyModelSerializer parser_classes = (FormParser, MultiPartParser) def post(self, *args, **kwargs): """ Create a MyModel --- parameters: - name: source description: file required: True type: file responseMessages: - code: 201 message: Created """ return super(MyModelView, self).post(self, *args, **kwargs)
All I had to do was change the parsers from FileUploadParser
to (FormParser, MultiPartParser)
It has been my experience that the FileUploadParser
works with this format of a request:
curl -X POST -H "Content-Type:multipart/form-data" \ -F "file=@{filename};type=image/jpg" \ https://endpoint.com/upload-uri/
The request.data['file']
in your view will have the file.
Maybe if you try a Content-Type:multipart/form-data
header, you will have luck.