Django REST Swagger實(shí)現(xiàn)指定api參數(shù)
為什么要指定swagger的api參數(shù)
api的參數(shù)有多種類型:
query 參數(shù),如 /users?role=admin
path 參數(shù),如 /users/{id}
header 參數(shù),如 X-MyHeader: Value
body 參數(shù),描述POST,PUT,PATCH請(qǐng)求的body
form 參數(shù),描述 Content-Type of application/x-www-form-urlencoded 和 multipart/form-data 的請(qǐng)求報(bào)文body的參數(shù)
swagger指定api參數(shù)就可以在文檔相應(yīng)的api條目中顯示出api的描述、正常輸出、異常輸出、參數(shù)的名稱、描述、是否必填、值類型、參數(shù)類型對(duì)不同的參數(shù)類型有不同的顯示效果。swagger是可交互的api文檔,可以直接填入文檔顯示的參數(shù)的值并發(fā)送請(qǐng)求,返回的結(jié)果就會(huì)在文檔中顯示。
難點(diǎn)
對(duì) Django REST Swagger < 2 的版本,要指定swagger的api參數(shù)非常容易,只要將相關(guān)說明以特定格式和yaml格式寫在相應(yīng)api的視圖函數(shù)的文檔字符串(DocStrings)里,swagger就會(huì)自動(dòng)渲染到文檔中。比如這樣的格式:
def cancel(self, request, id): ''' desc: 取消任務(wù),進(jìn)行中的參與者得到報(bào)酬 ret: msg err: 404頁面/msg input: - name: id desc: 任務(wù)id type: string required: true location: path '''
但是在2.0版本之后,Django REST Swagger廢棄了對(duì)yaml文檔字符串的支持,不會(huì)渲染出任何內(nèi)容。
一種解決方案
在Django REST framework基于類的api視圖中定義filter_class過濾出模型(models)的特定字段,swagger會(huì)根據(jù)這些字段來渲染。
from django_filters.rest_framework.filterset import FilterSetclass ProductFilter(FilterSet): class Meta(object): models = models.Product fields = ( ’name’, ’category’, ’id’, )class PurchasedProductsList(generics.ListAPIView): ''' Return a list of all the products that the authenticated user has ever purchased, with optional filtering. ''' model = Product serializer_class = ProductSerializer filter_class = ProductFilter def get_queryset(self): user = self.request.user return user.purchase_set.all()
這個(gè)解決方法只解決了一半問題,只能用在面向模型的api,只能過濾模型的一些字段,而且api參數(shù)名與模型字段名不一致時(shí)還要額外處理。
啟發(fā)
查閱Django REST Swagger的文檔,Advanced Usage提到,基于類的文檔api視圖是這樣的:
from rest_framework.response import Responsefrom rest_framework.schemas import SchemaGeneratorfrom rest_framework.views import APIViewfrom rest_framework_swagger import renderersclass SwaggerSchemaView(APIView): permission_classes = [AllowAny] renderer_classes = [ renderers.OpenAPIRenderer, renderers.SwaggerUIRenderer ] def get(self, request): generator = SchemaGenerator() schema = generator.get_schema(request=request) return Response(schema)
說明文檔是根據(jù)schema變量來渲染的,所以可以通過重載schema變量,利用yaml包解析出api視圖函數(shù)的文檔字符串中的參數(shù)定義賦值給schema變量。
更好的解決方法
創(chuàng)建schema_view.py:
from django.utils.six.moves.urllib import parse as urlparsefrom rest_framework.schemas import AutoSchemaimport yamlimport coreapifrom rest_framework_swagger.views import get_swagger_viewclass CustomSchema(AutoSchema): def get_link(self, path, method, base_url): view = self.view method_name = getattr(view, ’action’, method.lower()) method_docstring = getattr(view, method_name, None).__doc__ _method_desc = ’’ fields = self.get_path_fields(path, method) try: a = method_docstring.split(’---’) except: fields += self.get_serializer_fields(path, method) else: yaml_doc = None if method_docstring: try: yaml_doc = yaml.load(a[1]) except: yaml_doc = None # Extract schema information from yaml if yaml_doc and type(yaml_doc) != str: _desc = yaml_doc.get(’desc’, ’’) _ret = yaml_doc.get(’ret’, ’’) _err = yaml_doc.get(’err’, ’’) _method_desc = _desc + ’n<br/>’ + ’return: ’ + _ret + ’<br/>’ + ’error: ’ + _err params = yaml_doc.get(’input’, []) for i in params: _name = i.get(’name’) _desc = i.get(’desc’) _required = i.get(’required’, False) _type = i.get(’type’, ’string’) _location = i.get(’location’, ’form’) field = coreapi.Field( name=_name, location=_location, required=_required, description=_desc, type=_type ) fields.append(field) else: _method_desc = a[0] fields += self.get_serializer_fields(path, method) fields += self.get_pagination_fields(path, method) fields += self.get_filter_fields(path, method) manual_fields = self.get_manual_fields(path, method) fields = self.update_fields(fields, manual_fields) if fields and any([field.location in (’form’, ’body’) for field in fields]): encoding = self.get_encoding(path, method) else: encoding = None if base_url and path.startswith(’/’): path = path[1:] return coreapi.Link( url=urlparse.urljoin(base_url, path), action=method.lower(), encoding=encoding, fields=fields, description=_method_desc )schema_view = get_swagger_view(title=’API’)
urls.py中指向schema_view:
from .schema_view import schema_viewurlpatterns = [ url(r’^v1/api/’, include([ url(r’^doc/’, schema_view), ])),
然后在需要指定api參數(shù)的視圖類(如APIView或ModelViewSet)中重載schema:
schema = CustomSchema()
以上這篇Django REST Swagger實(shí)現(xiàn)指定api參數(shù)就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持好吧啦網(wǎng)。
相關(guān)文章:
1. python excel和yaml文件的讀取封裝2. moment轉(zhuǎn)化時(shí)間戳出現(xiàn)Invalid Date的問題及解決3. python爬蟲實(shí)戰(zhàn)之制作屬于自己的一個(gè)IP代理模塊4. Android Studio插件5. php實(shí)現(xiàn)當(dāng)前用戶在線人數(shù)6. Android中的緩存7. Python中內(nèi)建模塊collections如何使用8. Android組件化和插件化開發(fā)9. .net6 在中標(biāo)麒麟下的安裝和部署過程10. java——Byte類/包裝類的使用說明
