Django – ネスト化されたAPI

準備するもの

・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が完成です。

実際に試してください。

お疲れ様です。