23

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)

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()),
)

私にとって、これはかなり単純なはずです。ただし、アップロードを機能させることはできません。私はいつもこのエラー応答を受け取ります: ここに画像の説明を入力

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.

ただし、ヘッダーは Request Payload プロパティで django-rest-swagger によって渡されています (chrome コンソールから)。

さらに情報が必要な場合は、お知らせください。

Django==1.8.8djangorestframework==3.3.2およびを使用してdjango-rest-swagger==0.3.4います。

4

3 に答える 3

8

コードにいくつかの変更を加えることで、これが機能するようになりました。

まず、 で、名前をmodels.pyに変更し、相対パスを使用してアップロード フォルダーを指定します。ファイルをバイナリ ストリームとしてアップロードすると、ファイル キー ( ) の下のディクショナリで使用できるため、最もクリーンなオプションは、同じ名前のモデル フィールドにマップすることです。ImageFieldfilerequest.datarequest.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)

serializer.py、ソース フィールドの名前をファイルに変更します。

class MyModelSerializer(serializers.ModelSerializer):

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

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)

これをテストするために Postman Chrome 拡張機能を使用しました。画像をバイナリとしてアップロードし、2 つのヘッダーを手動で設定しました。

Content-Disposition: attachment; filename=upload.jpg
Content-Type: */*
于 2016-04-26T22:01:25.660 に答える
6

これが私が思いついた最終的な解決策です:

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)

于 2016-06-10T17:59:06.800 に答える
3

FileUploadParserがこの形式のリクエストで機能することは、私の経験です。

    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ヘッダーを試してみると、運がいいかもしれません。

于 2016-04-26T22:09:53.623 に答える