プログレッシブ・プロレタリアート

無産階級エンジニアが生きる知恵をはき出すブログ

Django SwaggerにQuery stringの項目も出したい!

環境

Django==1.11
django-rest-swagger==2.1.1
djangorestframework==3.6.1
coreapi==2.3.0

やりたいこと

swaggerにそのapiで対応しているQuerystringの項目名を表示してやりたい。
例) クエリストリングで日付を指定する必要があるapi
xxx.com/api/access_data?start=2013-03-04&end=2018-02-02

QueryStringのチェックはSerializerを使いたいのでSerializerを宣言したらそこの項目が自動的にswaggerに表示されると良いな

★最終的にできた画面 f:id:darakunomiti:20180404231728j:plain

やったこと


とりあえず、表示したいselializerを宣言する
selializer.py

class XxxxParameterSerializer(serializers.Serializer):

    start = serializers.CharField(help_text='開始日(yyyy-mm)', required=True)
    end = serializers.CharField(help_text='終了日(yyyy-mm)', required=True)

・Swaggerに返す用のBaseFilterBackendを宣言
ここでSerializerに書かれた内容を読んでcoreapiFieldにセットする。
serializerはserializer_classで宣言したものが渡ってきます。

import coreapi
from rest_framework.filters import BaseFilterBackend


class SwaggerQueryStringFilter(BaseFilterBackend):
    """
    create query string parameter for swagger
    """
    def get_schema_fields(self, view):
        fields = []
        for key, value in view.serializer_class._declared_fields.items():
            field = coreapi.Field(name=key, description=value.help_text, required=value.required, location="query",)
            fields.append(field)
        return fields

上記の二つをviewにセットする。
view.py

class MyApiView(APIView):

    serializer_class = XxxxParameterSerializer
    filter_backends = (SwaggerQueryStringFilter,)

    def get(self, request):
        """
        # コメント書くよ
        """return Response(datas)

ベストな方法かどうかは分かりませんが、とりあえず自分はこの方法で解決しました。

こつとしては filter_backends の宣言を一つだけにして汎用的に使えるようにしたぐらいでしょうか。

他のViewSetとかの時は?


ModelViewSet だと modelやserializerの宣言がされていると思うのでそれが表示されます。
その際には model.pyの書くフィールドの宣言のhelp_textがディスクリプションに表示されるのでhelp_textをがんがん書くといいのかなと思います。

調査するときに困ったこと


swagger 0.3の話がいっぱいあった →swagger0.3と 2系はかなり破壊的な変更がはいっているのでyamlにコメント云々みたいなのは0.3の話なので無視しましょう。

課題


Django swaggerってexampleとかtypeって表示できないのかなぁ・・・・(今の表示項目だけだとちょっと物足りない)

感想


APIのドキュメントを作るのはしんどいし、なにもないのもしんどいような場合swaggerがドキュメントの代わりを出来れば良いなと思って今回トライしてみました。
ただでさえ少ないDjangoエンジニアでDjangoRestFrameworkを使っててswaggerを使ってqueryStringをここに表示させたいなんて需要日本で他にあるのだろうか・・・