2016-10-21 9 views
18

昨日私は素晴らしいスキーマ生成が必要なので、Django Rest Frameworkを3.5.0にアップグレードしました。django rest swaggerで応答メッセージのリストを生成するには?

Django Rest Swaggerを使用してAPIを文書化していますが、APIエンドポイントが提供する可能性のあるすべての応答メッセージをリストする方法はわかりません。

エンドポイントが実行しているアクションに対応する成功メッセージが自動的に生成されているようです。 POSTアクションは、説明なしで201個の応答コードを生成します。どのように私は私のエンドポイントが提供するすべての応答メッセージの追加については行くし、それらにいくつかの説明を与えるだろう

enter image description here

私が使用しています

djangorestframework==3.5.0

django-rest-swagger==2.0.7

答えて

16

ああ、最後にそれを得ました。

しかし!これはハックのハックです - おそらくdrf + drfはそれをサポートしていません。基本的な問題は、OpenAPIのコーデックむしろ、DRFとDRF闊歩コードに接続されていない、自分自身を参照してください。

def _get_responses(link): 
    """ 
    Returns minimally acceptable responses object based 
    on action/method type. 
    """ 
    template = {'description': ''} 
    if link.action.lower() == 'post': 
     return {'201': template} 
    if link.action.lower() == 'delete': 
     return {'204': template} 
    return {'200': template} 

上記のコードはで見つけることができます:openapi_codec/encode.py - これは、DRFとどのような方法で接続されていませんgithub またはdrf swagger - リンクごとに(例:GET/api/v1/test /)、空の記述を持つテンプレートを作成します。

もちろん、この問題を克服する可能性があります。しかし、私は言ったように - これは私があなたとの例を共有することになります:)ハックにハックです:

docs_swagger.views.py

from rest_framework import exceptions 
from rest_framework.permissions import AllowAny 
from rest_framework.renderers import CoreJSONRenderer 
from rest_framework.response import Response 
from rest_framework.views import APIView 
from rest_framework_swagger import renderers 

from docs_swagger.schema_generator import CustomSchemaGenerator 


def get_swagger_view(title=None, url=None): 
    """ 
    Returns schema view which renders Swagger/OpenAPI. 

    (Replace with DRF get_schema_view shortcut in 3.5) 
    """ 
    class SwaggerSchemaView(APIView): 
     _ignore_model_permissions = True 
     exclude_from_schema = True 
     permission_classes = [AllowAny] 
     renderer_classes = [ 
      CoreJSONRenderer, 
      renderers.OpenAPIRenderer, 
      renderers.SwaggerUIRenderer 
     ] 

     def get(self, request): 
      generator = CustomSchemaGenerator(title=title, url=url) # this is altered line 
      schema = generator.get_schema(request=request) 
      if not schema: 
       raise exceptions.ValidationError(
        'The schema generator did not return a schema Document' 
       ) 
      return Response(schema) 

    return SwaggerSchemaView.as_view() 

次のように私はCustomSchemaGeneratorで行うことである。

docs_swagger.schema_g​​enerator.py

import urlparse 
import coreapi 
from rest_framework.schemas import SchemaGenerator 

from openapi_codec import encode 


def _custom_get_responses(link): 
    detail = False 
    if '{id}' in link.url: 
     detail = True 
    return link._responses_docs.get(
     '{}_{}'.format(link.action, 'list' if not detail else 'detail'), 
     link._responses_docs 
    ) 


# Very nasty; Monkey patching; 
encode._get_responses = _custom_get_responses 


class CustomSchemaGenerator(SchemaGenerator): 

    def get_link(self, path, method, view): 
     """ 
     Return a `coreapi.Link` instance for the given endpoint. 
     """ 
     fields = self.get_path_fields(path, method, view) 
     fields += self.get_serializer_fields(path, method, view) 
     fields += self.get_pagination_fields(path, method, view) 
     fields += self.get_filter_fields(path, method, view) 

     if fields and any([field.location in ('form', 'body') for field in fields]): 
      encoding = self.get_encoding(path, method, view) 
     else: 
      encoding = None 

     description = self.get_description(path, method, view) 

     if self.url and path.startswith('/'): 
      path = path[1:] 

     # CUSTOM 
     data_link = coreapi.Link(
      url=urlparse.urljoin(self.url, path), 
      action=method.lower(), 
      encoding=encoding, 
      fields=fields, 
      description=description 
     ) 

     data_link._responses_docs = self.get_response_docs(path, method, view) 

     return data_link 

    def get_response_docs(self, path, method, view): 
     return view.responses_docs if hasattr(view, 'responses_docs') else {'200': { 
      'description': 'No response docs definition found.'} 
     } 

そして最後に:

my_view.py

class TestViewSet(viewsets.ModelViewSet): 
    queryset = Test.objects.all() 
    serializer_class = TestSerializer 

    responses_docs = { 
     'get_list': { 
      '200': { 
       'description': 'Return the list of the Test objects.', 
       'schema': { 
        'type': 'array', 
        'items': { 
         'type': 'object', 
         'properties': { 
          'id': { 
           'type': 'integer' 
          } 
         } 
        } 
       } 
      }, 
      '404': { 
       'description': 'Not found', 
       'schema': { 
        'type': 'object', 
        'properties': { 
         'message': { 
          'type': 'string' 
         } 
        } 
       }, 
       'example': { 
        'message': 'Not found.' 
       } 
      } 
     }, 
     'get_detail': { 
      '200': { 
       'description': 'Return single Test object.', 
       'schema': { 
        'type': 'object', 
        'properties': { 
         'id': { 
          'type': 'integer' 
         } 
        } 
       } 
      }, 
      '404': { 
       'description': 'Not found.', 
       'schema': { 
        'type': 'object', 
        'properties': { 
         'message': { 
          'type': 'string' 
         } 
        } 
       }, 
       'example': { 
        'message': 'Not found.' 
       } 
      } 
     } 
    } 

私はこれを実際の解決策の代わりにもっと楽しいものと考えています。現実の解決策は、現在の状態では達成することはおそらく不可能です。おそらく、あなたはドロー・スワッガーのクリエイターに尋ねるべきです - 彼らはレスポンスをサポートする計画を持っていますか?

とにかく、闊歩のUI::)

+5

コーディング enter image description here

ハッピーは「たぶん、あなたはDRFの闊歩のクリエイターに依頼する必要があります - 彼らは応答をサポートする計画を持っているのですか?」 - 正しい。 RESTフレームワークのスキーマ生成には、まだ応答スキーマ情報は含まれていません。 Django RESTフレームワーク*の3.6リリースは、まだ提供されていませんが、可能性があります。 –

+0

ちょっとセバスチャン、ありがとうございました。 Tomは、3.6で適切なレスポンススキーマが提供されるわけではないと述べたので、私はカスタムレスポンススキーマを実装するためにあなたの答えを頻繁に使用します。 – Erika

+1

タイプ 'object'の' items'で 'list'型のスキーマを定義しても、UIのオブジェクトのリストは表示されませんでした。代わりに、私はテキスト 'リスト'を取得します。 'type'の値を' list'ではなく 'array'に変更したときにうまくいきました。 –

関連する問題