pythondjangodjango-rest-frameworkswaggerdjango-swagger

Django REST Framework + Django REST Swagger + ImageField


I created a simple Model with an ImageField and I wanna make an api view with django-rest-framework + django-rest-swagger, that is documented and is able to upload the file.

Here is what I got:

models.py

from django.utils import timezone
from django.db import models

class MyModel(models.Model):

    source = 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.source.url)

serializer.py

from .models import MyModel

class MyModelSerializer(serializers.ModelSerializer):

    class Meta:
        model = MyModel
        fields = [
            'id',
            'source',
            'created_at',
        ]

views.py

from rest_framework import generics
from .serializer import MyModelSerializer

class MyModelView(generics.CreateAPIView):
    serializer_class = MyModelSerializer
    parser_classes = (FileUploadParser, )

    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)

urls.py

from weddings.api.views import MyModelView

urlpatterns = patterns(
    '',
    url(r'^/api/mymodel/$', MyModelView.as_view()),
)

For me this should be pretty simple. However, I can't make the upload work. I always get this error response: enter image description here

I've read this part of the documentation from django-rest-framework:

If the view used with FileUploadParser is called with a filename URL keyword argument, then that argument will be used as the filename. If it is called without a filename URL keyword argument, then the client must set the filename in the Content-Disposition HTTP header. For example Content-Disposition: attachment; filename=upload.jpg.

However the Header is being passed by django-rest-swagger in the Request Payload property (from chrome console).

If any more info is necessary, please let me know.

I'm using Django==1.8.8, djangorestframework==3.3.2 and django-rest-swagger==0.3.4.


Solution

  • This is the final solution I came up with:

    from rest_framework import generics
    from rest_framework.parsers import FormParser, MultiPartParser
    from .serializer import MyModelSerializer
    
    class 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)