2016-04-18 22 views
17

ImageFieldを使用して単純なモデルを作成しましたが、django-rest-framework + django-rest-swaggerを使用してapiビューを作成したいと考えています。 。ここでDjango RESTフレームワーク+ Django REST Swagger + ImageField

は、私が得たものである:

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

これはかなり簡単にする必要があります。しかし、私はアップロード作業をすることはできません。ヘッダーは、要求ペイロードにジャンゴ - 休息 - 闊歩によって渡されているが

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-frameworkからドキュメントのこの部分を読んだ enter image description here

:私は常に、このエラー応答を取得しますプロパティ(クロムコンソールから)

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

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

+0

FileUploadParserからパーサーを変更したあなたは枕がインストールされていますか?私はdjango restが画像ファイルを処理するためにそれを必要とすると信じています https://pypi.python.org/pypi/Pillow –

+0

ありがとうチャールズ..しかし、はい、私は枕がインストールされています。 – jarussi

答えて

3

これは私が思い付いた最終的な解決策である:

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) 

私がしなければならなかったすべては(FormParser, MultiPartParser)

+0

DRFまたはDRF-Swaggerでymlを取得するには、何をする必要がありますか?私はそのようなドキュメントストリングを設定しましたが、単に "Implementation Notes"の下にMarkdownとしてレンダリングします –

+0

私の設定にはあまりありません。 Django-rest-swaggerのドキュメントの基本的な部分はかなりわかります。しかし、私はdjango-rest-swaggerのバージョン「0.3.7」を使っています。 – jarussi

7

私はあなたのコードにいくつかの変更を加えることでこれを実現しました。

最初にmodels.pyImageFieldの名前をfileに変更し、フォルダをアップロードする相対パスを使用します。ファイルをバイナリストリームとしてアップロードする場合は、request.dataディクショナリファイルキー(request.data.get('file'))で利用できるので、同じ名前のモデルフィールドにマップするのが一番クリーンな方法です。 serializer.py

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) 

、ファイルにソースフィールドの名前を変更します。)(作成、views.pyで

class MyModelSerializer(serializers.ModelSerializer): 

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

スーパーを呼び出すことはありませんが、呼び出し:

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拡張機能を使用しました。request.data['file']はあなたに

curl -X POST -H "Content-Type:multipart/form-data" \ 
       -F "[email protected]{filename};type=image/jpg" \ 
       https://endpoint.com/upload-uri/ 

:要求のこの形式でFileUploadParser作品ということ

Content-Disposition: attachment; filename=upload.jpg 
Content-Type: */* 
+0

あなたが提案した変更を試しましたが、別のエラーが発生しました: '有効な画像をアップロードしてください。あなたがアップロードしたファイルは、画像でも壊れた画像でもありませんでした。 ' – jarussi

3

それは私の経験をされている:私は、バイナリとして画像をアップロードしたと私は手動で2つのヘッダを設定しましたビューにファイルがあります。

Content-Type:multipart/form-dataヘッダーを試してみると、運がよいでしょう。

+0

ありがとうございます。でも、私はまだエラーが出ます: '{" file ":["投稿されたファイルは空です。それはうまくいかなかった。 – jarussi

+0

'curl'でファイルを呼び出し、ファイル名が' {} 'の中にあるようにして 'file = @ {path/to/file}'のように見えるかもしれません。 -側。がんばろう! – zemekeneng

関連する問題