私がよりクリーンでメンテナンスしやすいと思う別のオプションを書きたいと思います。defaultRouterを使用してビューセットのCRUD URLを追加し、同じビューセット内のアップローダービューを指定するもう1つの固定URLを追加します。
**** 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),
]
.- README。
マジックは、@ actionデコレーターをクラスメソッド 'uploader'に追加すると発生します。"methods = ['put']"引数を指定すると、PUTリクエストのみが許可されます。ファイルのアップロードに最適です。
また、引数「parser_classes」を追加して、コンテンツを解析するパーサーを選択できることを示しています。rest_framework_csvパッケージからCSVParserを追加して、この機能が必要な場合に特定のタイプのファイルのみを受け入れる方法を示します。私の場合、「Content-Type:text / csv」のみを受け入れます。注:カスタムパーサーを追加する場合は、リクエストがアップローダーメソッドパーサーにアクセスする前に許可されたmedia_typeをメイン(クラス)パーサーと比較するため、ViewSetのparsers_classesでそれらを指定する必要があります。
次に、Djangoにこのメソッドに移動する方法と、URLのどこに実装できるかを伝える必要があります。これは、固定URLを追加するときです(単純な目的)。このURLは、後でメソッドに渡される「ファイル名」引数を取ります。このメソッドを "uploader"に渡し、リストでhttpプロトコル( 'PUT')を指定してPostsViewSet.as_viewメソッドに渡す必要があります。
次のURLに着陸した場合
http://example.com/posts/uploader/
「Content-Type」とContent-Disposition:添付ファイルを指定するヘッダーを含むPUTリクエストが必要です。filename = "something.csv"。
curl -v -u user:pass http://example.com/posts/uploader/ --upload-file ./something.csv --header "Content-type:text/csv"