Django REST frameworkでアプリケーション開発 ~カスタムユーザー作成編~

Django REST frameworkで、Webアプリケーション開発をしましょう。

とは言いつつ、今回は、Djanog REST frameworkは出てきません。先にDjangoの基本的な開発をカスタムユーザーを作りながら体験してみましょう。

記事まとめ

プロジェクト作成

次の記事で、開発に必要なディレクトリやファイルを準備してください。

最終的に以下の構成になっていれば、OKです。

準備が整ったら次のコマンドで、ビルドします。

ビルドが完了したらmakeコマンドでDjangoプロジェクトを作成します。

このコマンドが正常に完了した場合、appフォルダ内にDjangoプロジェクトが作成されます。

accountアプリケーション

accountアプリケーションには、「カスタムユーザー」を作成します。

カスタムユーザーとは、Djangoの既存のユーザー設定をカスタマイズ版にしたものです(その名の通りですね、すみません)。

セットアップ

まずは、次のコマンドでaccountアプリケーションを作成してください。

app/app/settings.pyを開いて、INSTALLED_APPSにaccountを登録します。

こうすることで、Djangoにaccountの存在を認識させます。

Modelの設定

機能を実装する前に、最初にテストを書きましょう。

最初にsettings.pyにPostgresの設定しておきます。

次に、accountフォルダ配下にあるtests.pyを削除し、testsフォルダおよびtest_models.pyを作成してください。

テストコードは、機能ごとに分けて書くのが普通です。具体的に「Model」に対してのテストコードをtest_models.pyに記載します。

続いて、appフォルダ内にpytestの設定ファイルを作成してください。

テストコードの実行は、pytestを使います。上記の設定は、pytestで実行するテストファイル、クラス、関数の設定とテスト実行を無視するディレクトリの指定をしています。

テストを実行します。

TypeErrorになりましたね。デフォルトのDjangoのユーザーは、Emailプロパティを持っていませんので、当然の結果と言えます。

それでは、モデルを実装していきます。

app/account/models.pyを次のように編集してください。

Djangoのモデルは「model.objects.all()」などで、データベースから値を取得することができます。

このobjectsは、”マネージャー“とも呼ばれており、自分で作成することもできます。

実際に作成したものは、「UserManager」です。

これをuserモデルのobjectsプロパティにセットすることで、「User.objects.create_user()」で、特定の情報を取得できるようになります。

Userモデルは、「AbstractBaseUser」と「PermissionsMixin」を継承したモデルでクラスを作成することで、既存のユーザーモデルをカスタマイズすることができます。

このカスタムユーザーをDjangoに認識させるために、settings.pyの末尾に次の設定を追加します。

最後にデータベースの設定を適用させましょう。

もしかしたら次のエラーに遭遇するかもしれません。

これは、カスタムユーザーを設定したことによる既存のユーザーデータとの競合を指しています。

カスタムユーザー設定前にマイグレーションを実行していた場合、新しく設定したカスタムユーザーのデータと競合を起こしてしまうので、一度データを削除する必要があります。

エラーになってしまった場合は、postgresコンテナに入りましょう。

マイグレーションを実行しましょう。

今度は、成功したはずです。

次にテストを実行します。

テストがパスしたと思います。

passedの後に、次のような文言が出力されるかもしれません。

これは、flake8のコードスタイルチェックに引っかかっています。

特に直さなくてもこの後の開発は行えるので、余力のある方はメッセージ内容に従って直してみてください。

Emailの正規化

次は、Emailの正規化のテストを行います。

正規化とは例えば、「test@SELFNOTE.WORK」と入力した場合でも「test@selfnote.work」で認識させるようにします。

テストを実行します。

エラーになりましたね。

models.pyのcreate_userを修正します。

組み込み関数の「normalize_email」を使って、正規化をしました。

テストを実行します。

Emailテスト

Emailは、必須項目です。設定されていない場合は、ValueErrorを発生するようにしましょう。

テストコードを書きます。

テストを実行します。

models.pyのcreate_userを修正します。

テストを実行します。

管理者ユーザー作成

次は、管理者ユーザーを作成できるようにします。

テストコードを書きましょう。

テストを実行しましょう。

エラーになりましたね。

app/account/models.pyのUserManagerに次の関数を追加しましょう。

テストを実行します。

テストがパスしましたね。

それでは、実際に次のコマンドで管理ユーザーを作成してみましょう。

管理者が作成できましたね。

次のコマンドで、dockerコンテナを起動しましょう。

「localhost:8000/admin」にアクセスして、管理画面に入れるか確認しましょう。

管理画面テスト

管理画面にカスタムユーザーが表示されていませんね。

Djangoでは、admin.pyにModelを登録することで、表示することができます。

では、表示させてみましょう。

まずは、テストファイルを用意して、テストコードを書きます。

上記のコードは、管理画面にUserモデルの一覧が表示されるかテストします。

公式サイトによると管理画面に表示するChangelistの構文は次のようになっています。

reverseメソッドは、指定の文字列からURLを逆引きする関数で、「admin:account_user_changelist」と指定すれば、「admin/account/user/」のURLを取得します。

テストを実行してみましょう。

NoReverseMatch」が出力されました。

管理画面にUserモデルを登録していないので、当然です。

app/account/admin.pyを編集しましょう。

テストを実行します。

テストがパスしましたね。

「localhost:8000/admin/account/user/」にアクセスしましょう。

今度は、表示されていますね。

注意)UsersのEmailをクリックするとエラー画面が表示されますが、後ほど修正します

ユーザー編集ページ

次は、ユーザーの編集ページをテストしてみましょう。

テストします。

FieldError」が表示されましたね。

admin.pyを次のように修正しましょう。

gettextは、多言語対応用のモジュールです。今回作るアプリケーションには関係ないのですが、Djangoではこのような実装が慣習なので、参考にしてください。

fieldsetsは、画面の表示項目を指定するプロパティです。カスタムユーザーのフィールドを指定しました。

テストを実行してみます。

パスしましたね。カスタムユーザーを設定したときは、fieldsetsが必須のようですね。

公式サイトにもそのようなことが書かれています。

If you are using a custom ModelAdmin which is a subclass of django.contrib.auth.admin.UserAdmin, then you need to add your custom fields to fieldsets (for fields to be used in editing users) and to add_fieldsets (for fields to be used when creating a user). For example:

公式サイトより

「localhost:8000/admin/account/user/1/change/」を表示させてみましょう。

エラーが回避できていると思います。

ユーザー追加ページ

ユーザー追加ページのテストもしてみましょう。

テストを実行します。

先ほどと同じエラーになりましたね。

admin.pyにadd_fieldsetsを追加します。

「add_fieldsets」を設定しました。

テストを実行します。

テストがパスしましたね。

「localhost:8000/admin/account/user/add/」にアクセスしてみましょう。

次回

カスタムユーザーの作り方は以上です。

次回は、Djangoのマネジメントコマンドを作成します。

関連記事

基礎編はこちらです。

Djangoおすすめ書籍

Djangoを学ぶなら以下の書籍がオススメです。

緑 -> 赤 -> 紫の順でやればOKです。読みやすい英語で書かれているので、英語力もついでに上がるかもしれません^^

コメントを残す