メリークリスマス!この記事はdjango advent calendarの25日目の記事です。
みんな今年はいい子にしてたかな? え?バグを出しまくったからサンタさんからプレゼントなしだって?
だったら自分でプレゼントを作るんだよ!
というわけで、今年もクリスマスはひとりぼっちで誰からもプレゼントはもらえそうにないので自分でプレゼントを書いてそっと置く自作自演サンタを演じようと思います。
よいこの皆さまにおかれましてはdjango使いであり、なし崩し的にdjango-restframeworkを使ってAPI実装をおこないリッチなウェブサイトを製作していることと存じますが、みんなそのAPIを利用するフォームってどうしているんでしょうか。
私がdjangoを利用する魅力を考えた時、真っ先に浮かぶのがAdmin画面です。その次に大抵浮かぶのがフォームです。
しかし、restframeworkを利用すると自動的にフォームを生成することができず、自分でフォームをかかなければなりません。
この問題をなんとか解消できないものかと、なんとか自動でHTML上にVue.JS用にフォームを吐かせるソリューションを考えて見ます。
TL;DR
Vue.JSで利用するフォームを面倒な事なく自動的に生成したい!
ただし、この方法はまだ実験段階なので、プロダクションでは利用しないようにしてください。
解説
django-restframeworkでAPIを実装中、APIにバインドされているURLをブラウザーで開くと何故以下のような入力画面が開くんだろうかと、不思議に思った経験はありませんか?
実はこれを追っていくと、Rendererに突き当たります。restframeworkは最終的なレスポンスをView関数ではなく、Rendererが返します。ようはView関数からのレスポンスを如何様にもすることができるのです。
Rendererはformatクエリパラメーター、およびブラウザーのAcceptをもとに選択されるため、ブラウザーで直接アクセスを行うと、BrowsableAPIRendererを通して、入力フォームなどが付加されます。
restframeworkにはサードパッケージを含めて様々なレンダラーがあります。中にはSwaggerのようなUIを表示したり、APIが利用するシリアライザーをJSON Schema形式で吐き出すものもあります。
ならば、アクセスしたURLにバインドされているAPIが利用するシリアライザーをなんとかJSON Schemaなどで吐き出し、Vue.JSでフォームを自動生成する vue-form-generatorに食わせれば自動でフォームが作れるはず!
というわけで、vue-form-generatorが必要とするスキーマ情報を吐き出すcodecと、そいつを返すためのrendererを書きました。その結果、フィールドの一つ一つについて返す情報をかかなきゃならんためcodecはかなり泥臭い感じになりました・・・これはもう仕方ない。
https://github.com/salexkidd/vue-form-generator/blob/master/vue_form_generator/renderers.py
https://github.com/salexkidd/vue-form-generator/blob/master/vue_form_generator/codec.py
あとはVue.JSでvue-form-generatorにスキーマを食わせるだけ!
結果発表
はい! っといってもこの見栄えだとどう見てもいつものdjangoのフォームです。本当にありがとうございました。
でも、フォーム内容のチェンジに合わせてその場でエラーチェックしてくれるんです!スゴイ!(自作自演)
というわけでHTMLの構造をみてみましょう。ほら!Vue.JS用に作られたフォームでしょ!?
しかしまだ開発途中なのです・・・
本当は使えるライブラリに仕立てて今後利用していこうと思ったんですが、実はこの開発中に人生における大きな波がきてしまったため、完成までに至りませんでした…すいません。
しかし、このおかげでVue.JSをdjangoに組み込むための方法をしれたのは良い経験になりました。
中途半端な記事で申し訳ありませんが、みなさんよいクリスマスを!
リポジトリ
開発中のものは下記においてあります。かなり修正余地があるので参考までにとどめていただければと思います。
https://github.com/salexkidd/vue-form-generator