首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Django REST框架+ Django REST Swagger + ImageField

Django REST框架+ Django REST Swagger + ImageField
EN

Stack Overflow用户
提问于 2016-04-19 02:42:06
回答 3查看 6.2K关注 0票数 20

我用一个ImageField创建了一个简单的模型,我想用django-rest-framework + django-rest-swagger创建一个api视图,这是有文档记录的,并且能够上传文件。

下面是我得到的信息:

models.py

代码语言:javascript
复制
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

代码语言:javascript
复制
from .models import MyModel

class MyModelSerializer(serializers.ModelSerializer):

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

views.py

代码语言:javascript
复制
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

代码语言:javascript
复制
from weddings.api.views import MyModelView

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

对我来说,这应该很简单。但是,我不能使上传工作。我总是得到这样的错误响应:

我已经阅读了来自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.

然而,头部是由请求有效负载属性中的django-rest-swagger传递的(从chrome控制台)。

如果需要更多的信息,请让我知道。

我使用的是Django==1.8.8djangorestframework==3.3.2django-rest-swagger==0.3.4

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2016-06-11 01:59:07

这是我想出的最终解决方案:

代码语言:javascript
复制
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)

我所要做的就是将解析器从FileUploadParser改为(FormParser, MultiPartParser)

票数 6
EN

Stack Overflow用户

发布于 2016-04-27 06:01:26

我通过对您的代码做了几处更改来实现这一点。

首先,在models.py中,将ImageField名称更改为file,并使用相对路径上传文件夹。当您以二进制流的形式上传文件时,它在request.data字典中的文件键(request.data.get('file'))下可用,因此最干净的选项是将其映射到同名的模型字段。

代码语言:javascript
复制
from django.utils import timezone
from django.db import models


class 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)

serializer.py中,将源字段重命名为文件:

代码语言:javascript
复制
class MyModelSerializer(serializers.ModelSerializer):

    class Meta:
        model = MyModel
        fields = ('id', 'file', 'created_at')

在views.py中,不要调用super,而是调用create():

代码语言:javascript
复制
from rest_framework import generics
from rest_framework.parsers import FileUploadParser

from .serializer import MyModelSerializer


class 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)

我已经使用Postman Chrome扩展来测试这一点。我已经将图片上传为二进制文件,并手动设置了两个头文件:

代码语言:javascript
复制
Content-Disposition: attachment; filename=upload.jpg
Content-Type: */*
票数 8
EN

Stack Overflow用户

发布于 2016-04-27 06:09:54

根据我的经验,FileUploadParser使用以下格式的请求:

代码语言:javascript
复制
    curl -X POST -H "Content-Type:multipart/form-data" \
                 -F "file=@{filename};type=image/jpg" \
                 https://endpoint.com/upload-uri/

视图中的request.data['file']将包含该文件。

也许如果你尝试一个Content-Type:multipart/form-data头,你会很幸运。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36701877

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档