準備するもの
・Django REST Frameworkのコード
チケットシステムの例
今日はこのチケット管理システムもモデルを元に説明します。
Djangoのアプリという概念で、このDjnagoプロジェクトに下記の3つのアプリが設定されております。
- Customers
- Members
- Tickets
では、それぞれもモデルを見ると、アプリに必要なデータベースのモデルがあることが分かりますね。
Foregin KeyがPKで表示される
通常、ViewSetやAPIViewで作成したForeignKeyの項目はそのキーのPK(プライマリーキー)で表示されます。これはデータベースを見ると分かりますが、DB自体がこの外部キーをPKとして保管しているからです。
これだとせっかくAPIにしてもクライアント側のアプリでは使い物になりませんね。
StringRelatedFieldの使い方
その問題を簡単に解決できるのがStringRelatedFieldです。
これはモデルで設定した__Str__の値を返してくれます。
def __str__(self): return self.inquiry
ただしこの問題は、これらのStringRelatedFieldを使うとReadOnlyのAPIになり、いざユーザー側からPOST(データの投稿)をしたい場合にエラーが発生します。
DjangoRESTのエンドポイントのHTMLフォームからも項目が削除されたことでも確認できますね。
ネスト化されたAPIモデル
ほかに、depthメタを使用してforeign keyの一階層下まで参照することができます。
この画像のようにモデルをシリアル化する際にforeign Keyでリファレンス(参照)しているキーをどの階層まで出力されるか設定することができます。
これも便利ですがReadOnlyです。
class Meta: model = Ticket fields = '__all__' # depth = 1
APIでForeignKeyを受け付ける方法
Django RESTフレームワークでも、外部キー(Foregin Key)の扱いは我々デベロッパーに任されており、魔法のようなソリューションはありません。と記載されております。
色々試した結果、このオープンソースのライブラリが一番簡単な解決方法だと思ったので紹介します。
このライブラリはBeda Sotwareというロシアの医療ソフト開発会社が提供しているようですね。
https://github.com/beda-software/drf-writable-nested
ではこのライブラリをインストールしましょう。
pip install drf-writable-nested
その後に単純にシリアライザーのパラメーターを下のように変えるだけです。
class TicketSerializer(WritableNestedModelSerializer): # category = CategorySerializer() # staff = MemberSerializer() # store = StoreSerializer()
で、それぞれのシリアライザーをインポートすればCRUDレディーのAPIが完成です。
実際に試してください。
お疲れ様です。