我想写一个我觉得更干净,更易于维护的选项。我们将使用defaultRouter为我们的视图集添加CRUD网址,并且还将添加一个固定的网址,以指定同一视图集内的上载器视图。
**** views.py
from rest_framework import viewsets, serializers
from rest_framework.decorators import action, parser_classes
from rest_framework.parsers import JSONParser, MultiPartParser
from rest_framework.response import Response
from rest_framework_csv.parsers import CSVParser
from posts.models import Post
from posts.serializers import PostSerializer
class PostsViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
parser_classes = (JSONParser, MultiPartParser, CSVParser)
@action(detail=False, methods=['put'], name='Uploader View', parser_classes=[CSVParser],)
def uploader(self, request, filename, format=None):
# Parsed data will be returned within the request object by accessing 'data' attr
_data = request.data
return Response(status=204)
项目的主要urls.py
**** urls.py
from rest_framework import routers
from posts.views import PostsViewSet
router = routers.DefaultRouter()
router.register(r'posts', PostsViewSet)
urlpatterns = [
url(r'^posts/uploader/(?P<filename>[^/]+)$', PostsViewSet.as_view({'put': 'uploader'}), name='posts_uploader')
url(r'^', include(router.urls), name='root-api'),
url('admin/', admin.site.urls),
]
.-自述文件。
当我们将@action装饰器添加到类方法'uploader'时,魔术发生了。通过指定“ methods = ['put']”参数,我们仅允许PUT请求;非常适合文件上传。
我还添加了参数“ parser_classes”,以显示可以选择将解析内容的解析器。我从rest_framework_csv包中添加了CSVParser,以演示如果需要此功能时我们如何仅接受某些类型的文件,在我的情况下,我仅接受“ Content-Type:text / csv”。注意:如果要添加自定义解析器,则需要在ViewSet的parsers_classes中指定它们,因为在访问上载器方法解析器之前,请求会将允许的media_type与主(类)解析器进行比较。
现在我们需要告诉Django如何使用此方法,以及可以在我们的url中实现的位置。那就是我们添加固定网址的时候(简单目的)。该网址将带有“文件名”参数,该参数稍后将在方法中传递。我们需要传递此方法“ uploader”,并在列表中指定http协议('PUT')到PostsViewSet.as_view方法。
当我们进入以下网址时
http://example.com/posts/uploader/
它将期望一个带有标头的PUT请求,该标头指定“ Content-Type”和Content-Disposition:附件;filename =“ something.csv”。
curl -v -u user:pass http://example.com/posts/uploader/ --upload-file ./something.csv --header "Content-type:text/csv"