2016-10-21 43 views
18

Tôi đã nâng cấp Django Rest Framework lên 3.5.0 ngày hôm qua vì tôi cần tạo lược đồ đẹp.Làm cách nào để tạo danh sách thư trả lời trong phần còn lại của django?

Tôi đang sử dụng Django Rest Swagger để ghi lại API của mình nhưng không biết cách liệt kê tất cả các thư trả lời có thể có mà điểm cuối API cung cấp.

Dường như có thông báo thành công tự động tương ứng với hành động mà điểm cuối của tôi đang thực hiện. Các hành động POST tạo mã phản hồi 201, không có bất kỳ mô tả nào.

enter image description here

Làm thế nào tôi sẽ đi về việc thêm tất cả các thông điệp trả lời rằng thiết bị đầu cuối của tôi cung cấp và cung cấp cho họ một số giới thiệu?

Tôi đang sử dụng

djangorestframework==3.5.0

django-rest-swagger==2.0.7

Trả lời

16

Ah, Cuối cùng đã nhận nó.

Nhưng! Đây là hack trên hack - và có lẽ drf + drf swagger không hỗ trợ điều đó; Về cơ bản các vấn đề không được kết nối với mã DRF và DRF vênh vang, chứ không phải các codec openapi, xem bản thân:

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} 

Đoạn mã trên có thể được tìm thấy tại địa chỉ: openapi_codec/encode.py-github này không được kết nối bằng mọi cách với DRF hoặc drf swagger - chỉ cho mỗi liên kết (ví dụ: GET/api/v1/test /) tạo mẫu có mô tả trống.

Tất nhiên, có khả năng khắc phục vấn đề này. Nhưng như tôi đã nói - đây là hack vào Hack :) tôi sẽ chia sẻ một ví dụ với bạn:

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

Những gì tôi làm trong CustomSchemaGenerator là như sau:

docs_swagger.schema_generator.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.'} 
     } 

Và cuối cùng:

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.' 
       } 
      } 
     } 
    } 

Tôi cho rằng điều này thú vị hơn thay vì giải pháp thực. Giải pháp thực sự có lẽ là không thể đạt được ở trạng thái hiện tại. Có lẽ bạn nên hỏi những người sáng tạo của vênh vênh drf - họ có kế hoạch để hỗ trợ phản ứng?

Dù sao, giao diện người dùng vênh vang: enter image description here

Chúc mừng mã hóa :)

+5

"? Có lẽ bạn nên hỏi những người sáng tạo của DRF vênh vang - làm họ có kế hoạch để hỗ trợ ứng phó" - Chính xác. Việc tạo lược đồ khung công tác REST không * được nêu ra * bao gồm bất kỳ thông tin lược đồ phản hồi nào. Bản phát hành 3.6 của khung công tác Django REST * có thể * làm, mặc dù đó chưa phải là một điều đã cho. –

+0

Hey Sebastian, cảm ơn rất nhiều vì giải pháp của bạn. Như Tom đã tuyên bố rằng nó không phải là một cho rằng một lược đồ đáp ứng thích hợp sẽ được vận chuyển trong 3.6, tôi sẽ sử dụng rất nhiều câu trả lời của bạn để triển khai lược đồ phản hồi tùy chỉnh. – Erika

+1

Xác định lược đồ kiểu 'danh sách' với' mục' thuộc loại 'đối tượng' không hiển thị danh sách các đối tượng trong giao diện người dùng. Thay vào đó, tôi chỉ nhận được văn bản 'danh sách'. Nó đã làm việc tốt khi tôi thay đổi giá trị 'type' thành' mảng' thay vì 'danh sách'. –

Các vấn đề liên quan