jar*_*ssi 19 python django swagger django-rest-framework django-swagger
我创建了一个带有ImageField的简单模型,我想用django-rest-framework + django-rest-swagger创建一个api视图,该文档已记录并能够上传文件.
这是我得到的:
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)
Run Code Online (Sandbox Code Playgroud)
serializer.py
from .models import MyModel
class MyModelSerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = [
'id',
'source',
'created_at',
]
Run Code Online (Sandbox Code Playgroud)
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)
Run Code Online (Sandbox Code Playgroud)
urls.py
from weddings.api.views import MyModelView
urlpatterns = patterns(
'',
url(r'^/api/mymodel/$', MyModelView.as_view()),
)
Run Code Online (Sandbox Code Playgroud)
对我来说这应该很简单.但是,我无法使上传工作.我总是得到这个错误响应:

我从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.
但是,Header在Request Payload属性中从django-rest-swagger传递(来自chrome控制台).
如果需要更多信息,请告诉我.
我正在使用Django==1.8.8,djangorestframework==3.3.2而且django-rest-swagger==0.3.4.
我通过对代码进行一些更改来实现这一点.
首先,在models.py,更改ImageField名称file并使用上传文件夹的相对路径.当您将文件作为二进制流上传时,它可以在request.data文件key(request.data.get('file'))下的字典中使用,因此最干净的选项是将其映射到具有相同名称的模型字段.
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)
Run Code Online (Sandbox Code Playgroud)
在serializer.py,将源字段重命名为file:
class MyModelSerializer(serializers.ModelSerializer):
class Meta:
model = MyModel
fields = ('id', 'file', 'created_at')
Run Code Online (Sandbox Code Playgroud)
在views.py中,不要调用super,而是调用create():
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)
Run Code Online (Sandbox Code Playgroud)
我使用Postman Chrome扩展程序来测试它.我已将图像作为二进制文件上传,我手动设置了两个标题:
Content-Disposition: attachment; filename=upload.jpg
Content-Type: */*
Run Code Online (Sandbox Code Playgroud)
这是我想出的最终解决方案:
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)
Run Code Online (Sandbox Code Playgroud)
我要做的就是将解析器从更改FileUploadParser为(FormParser, MultiPartParser)
| 归档时间: |
|
| 查看次数: |
3552 次 |
| 最近记录: |