9_Django REST framework入門 ~ProfileFeedAPIの作成~

Django REST framework
とんぺい
とんぺい

師匠〜!!

おはよう〜!今日もDjango REST frameworkの続きを勉強しに来たブゥ!

師匠
師匠

とんぺいくん、おはよう。

前回はLoginAPIの実装を行ったね。今日は、ユーザの状態一覧を表示するProfileFeedAPIを作成しよう。

とんぺい
とんぺい

それは楽しみだブゥ!

今日もよろしくお願いします!

注意

  • コード中に[という文字列がありますが、これは [ が文字化けしたものです。
  • 今後修正法が判明次第修正いたします。

Django REST framework入門一覧

ソースコード

modelの定義

師匠
師匠

APIを作成する際に第一にすべきことは、modelの定義だったね。profiles_apimodels.pyを編集しよう。

とんぺい
とんぺい

承知しました!modelはDjango REST frameworkにおいて、データベースにどういったデータを保存したいか定義するところだったブゥね〜!

師匠
師匠

ProfilesFeedItemで保存したいデータはuser_profile(ユーザの識別)、status_text(ユーザの状態)、created_on(作成日時)になるので、それぞれ定義しよう。

とんぺい
とんぺい

それぞれのデータの定義は完了したブゥ!

だけどmodels.ForeignKeyについてわからないから、解説をお願いしたいブゥ!

師匠
師匠

models.ForeignKeyを使用することで多:1の関係で外部キーを設定することができるよ。今回の場合だと「多=ProfileFeedItem」、「1=user_profile」になるね。

とんぺい
とんぺい

ほぅほぅ。それぞれのmodelで関係をもたせたい場合にmodels.ForeignKeyを使うんだブゥね!on_delete=models.CASCADEはどういった意味があるブゥか?

師匠
師匠

on_deleteは外部キーが削除された場合に、外部キーに関連付けられたデータをどのように扱うか記述したところだよ。on_delete=CASCADEの場合は外部キーが削除された際に、一緒に関連付けられているデータも削除する設定だね。

とんぺい
とんぺい

ふんふん。

じゃあ、今回の場合はuserのデータが削除されたら、一緒にProfileFeedItemも削除されるということだブゥね!

師匠
師匠

その通り。modelsの編集が完了したら、terminalで以下のコマンドを入力してmigrationファイルを作成しよう。

$ docker-compose run --rm app sh -c 'python manage.py makemigrations'

とんぺい
とんぺい

無事にmigrationファイルの作成ができたブゥ!

師匠
師匠

では続いて、terminalで以下のコマンドを入力しデータベースにmigrationファイルを適用しよう。

$ docker-compose run --rm app sh -c 'python manage.py migrate'

とんぺい
とんぺい

migrateも無事に完了したブゥ!

Serializerの作成

師匠
師匠

modelsの作成が完了したら、次にSerializerの作成に入るよ。profiles_apiserializers.pyを編集しよう。

とんぺい
とんぺい

Serializersはデータの入出力を扱って、DBとPythonのそれぞれの領域で適切にデータを扱えるようにする役割があったブゥね!

師匠
師匠

models.pyProfileFeedItemの定義を行っているので、Serializerを作成する時はModelSerializerを使用するよ。class Meta()にSerializerを通したいデータを記述しよう。

とんぺい
とんぺい

今回はuser_profileread_onlyになっているブゥね。なんでread_onlyにしたブゥか?

師匠
師匠

user_profileread_onlyにすることで、ユーザがProfileFeedItemを投稿するときに、手動でuser_profileを設定できなくしているよ。

とんぺい
とんぺい

ほぅほぅ。じゃあ、どのユーザが投稿したのかを表すuser_profileはどうやって設定するんだブゥか?

師匠
師匠

user_profileはユーザがログインの際に取得したTokenから自動的に反映できるようにプログラムを組むよ。これは次のViewで実装するよ。

とんぺい
とんぺい

了解だブゥ!

それでは次はProfileFeedItemのViewの設定に行くブゥ!

Viewの作成

師匠
師匠

Serializerの作成が終わったら、Viewの作成に入ろう。profiles_apiviews.pyを編集しよう。

とんぺい
とんぺい

Viewは具体的にどのような形でAPIを提供するのか、そのロジックを定義したところだったブゥね!

師匠
師匠

先程の話でもあったように、ここでperform_create()をオーバーライドして、自動的にself.request.useruser_profileに代入されるようにするよ。

とんぺい
とんぺい

ほぅほぅ!それはコメントにも書いてある通りだブゥね!serializer.save(data=data)を用いることで、viewsetでPOSTメソッドが実行される際に、自動的に指定したデータを保存できるブゥね!

師匠
師匠

その通りだ。では、Viewの編集も完了したら、次はURLの設定を行い、Viewが呼び出されるようにしよう。

URLの設定

とんぺい
とんぺい

ここはそんなに難しいことはないブゥね!

ProfileFeedItemはviewsetsを用いてViewの作成をしたから、routerでURLを自動的に作成できるブゥ!

師匠
師匠

その通りだ。URLの設定が完了したら、ブラウザで動作確認をしよう。terminalでdocker-compose upと入力してhttp://localhost:8000/api/feed/にアクセスするよ。

とんぺい
とんぺい

無事に表示されているブゥ!

師匠
師匠

では、ModHeaderを用いてheaderに仮想的にtokenを持たせから、POSTメソッドを実行してみよう。

とんぺい
とんぺい

POSTメソッドも無事に実装できているみたいだブゥ!

師匠
師匠

では今度は、ModHeaderを停止してもう一度POSTメソッドを実行してみよう。

とんぺい
とんぺい

 ぶぶぅ!

ValueErrorが表示されているブゥ!

これは何が起こったんだブゥか?

師匠
師匠

この例外は、ユーザが特定されていない状態でPOSTメソッドを実行したので、起こったエラーだね。ModHeaderのTokenを解除しているので、Django REST framework側でユーザの特定ができないことが原因だよ。

とんぺい
とんぺい

ほぅほぅ!

だけど、例外エラーが出るのは、エラーハンドリングができていない証拠だから、駄目だって効いたことがあるブゥ!

師匠
師匠

そうだね。解決策として、例外エラーが出ないように、UserProfileFeedViewSetにpermissionを追加しよう。

Permissionの追加

師匠
師匠

では、profiles_apipermissions.pyを編集して、まずは自分が投稿したProfileFeedItemのみ更新が行えるようにするよ。

とんぺい
とんぺい

これは、以前ユーザの情報を更新できるのを自分自身だけにした時と同じロジックだブゥね!

師匠
師匠

そうだね。では、Permissionの実装が完了したらViewに戻って、Permissionの設定を行おう。

とんぺい
とんぺい

今回は、permissions.UpdateOwnStatus以外にもIsAuthenticatedをPermissionに追加しているブゥね!!

IsAuthenticatedはどんなPermissionなんだブゥか?

師匠
師匠

IsAuthenticatedは文字が示すとおりに、認証を行っているユーザかどうかを評価し、その評価を元にAPIにアクセスできるよう許可を与えているよ。

とんぺい
とんぺい

これはDjango REST frameworkにデフォルトで実装されているんだブゥね!すごく便利だブゥ!

師匠
師匠

今後は、新機能を追加する際に、フレームワーク側で実装されていないか調査を行うのが大切だね。では、ここまで実装が完了したら、ブラウザを開いてhttp://localhost:8000/api/feed/にアクセスしよう。

とんぺい
とんぺい

今度は例外エラーじゃなくて、「認証されていませんよ〜」ってエラーが返ってきてるブゥね!エラーハンドリングがちゃんとできている証拠だブゥ!

師匠
師匠

うまくいったようだね。これらのPermissionを加えることで、認証できていないユーザーは投稿ができなくなり、投稿されたItemも自身の投稿しか編集できなくなったね。

まとめ

師匠
師匠

それでは本日はここまで。今日は以下の点について学習したね。

  • ProfileFeedAPIの実装
  • model同士の連携(models.ForeignKey)
  • IsAuthenticated(認証済みのユーザのみ許可)
とんぺい
とんぺい

うん!

今回学んだ内容を用いたら、なんだか会員制サービスが作れそうな気がしてきたブゥ!

師匠
師匠

では、Django REST frameworkの入門編は本日で終了だ。

次回からはDjango REST frameworkの応用編に取り組もう。

とんぺい
とんぺい

応用編もあるんだブゥね!続きが楽しみだブゥ!

今日はありがとうございました!また次回だブゥ!

参考

コメント

タイトルとURLをコピーしました