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 FilterSet class 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 Response from rest_framework.schemas import SchemaGenerator from rest_framework.views import APIView from rest_framework_swagger import renderers class 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 urlparse
from rest_framework.schemas import AutoSchema
import yaml
import coreapi
from rest_framework_swagger.views import get_swagger_view
class 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_view urlpatterns = [ 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è)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python操作系統(tǒng)的6個(gè)自動(dòng)化腳本小結(jié)
在Python中,實(shí)現(xiàn)操作系統(tǒng)自動(dòng)化的腳本可以涵蓋從文件操作、系統(tǒng)監(jiān)控到網(wǎng)絡(luò)任務(wù)等多種功能,下面我將詳細(xì)介紹六個(gè)不同類別的Python自動(dòng)化腳本示例,這些示例將幫助你理解如何用Python來自動(dòng)化日常操作系統(tǒng)任務(wù),需要的朋友可以參考下2024-10-10
Django 簡單實(shí)現(xiàn)分頁與搜索功能的示例代碼
這篇文章主要介紹了Django 簡單實(shí)現(xiàn)分頁與搜索功能的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-11-11
為何人工智能(AI)首選Python?讀完這篇文章你就知道了(推薦)
這篇文章主要介紹了為何人工智能(AI)首選Python,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
Python爬蟲獲取國外大橋排行榜數(shù)據(jù)清單
這篇文章主要介紹了Python爬蟲獲取國外大橋排行榜數(shù)據(jù)清單,文章通過PyQuery?解析框架展開全文詳細(xì)內(nèi)容,需要的小伙伴可以參考一下2022-05-05
Pycharm使用爬蟲時(shí)遇到etree紅線問題及解決
這篇文章主要介紹了Pycharm使用爬蟲時(shí)遇到etree紅線問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-05-05
python scipy.misc.imsave()函數(shù)的用法說明
這篇文章主要介紹了python scipy.misc.imsave()函數(shù)的用法說明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2021-05-05

