【Django(日報アプリ開発)】signals post_save を使って、Profileを自動作成しよう!

Django

(最終更新月:2021年9月)

前回の記事では、ごちゃごちゃしてきたファイル関数クラスを整理する方法について解説しました

アプリ開発も順調に進んできており、次の問題に取り組みます

今のままですと、新たにユーザー登録をするたびに、拡張クラスである「Profile」をいちいちスーパーユーザーが作成しなければいけません

Webアプリでいちいちスーパーユーザーが処理をするのは大変ですね

そこで、当記事を通じて、

  • シグナル post_saveを使って、Profileを自動作成、保存する方法

を解説し、ユーザー登録とProfile作成を連動させていきます

まずはシグナルのコードからご覧いただきます

関連書籍

シグナルのコードを紹介

accounts > models.py 内、一番下に下記を追記します

from django.db.models.signals import post_save

def post_user_created(sender, instance, created, **kwargs):
    if created:
        profile_obj = Profile(user=instance)
        profile_obj.username = instance.email
        profile_obj.save()

post_save.connect(post_user_created, sender=User)

post_saveメソッドを使い、Userクラスが保存された後すぐに「Profile」クラスを作成するよう関数を定義しました

ユーザー名は初期値として、Userオブジェクトのemailにしています

当記事では細かい説明は省きますので、「シグナルについて詳しく知りたい!」という方はこちらをご覧ください↓

テストの実行

post_saveメソッドが正しく機能しているか試してみましょう

アドミンページやシェルを使っていくつかユーザーを作って試してみるのも良いですが、テストプログラムを作れば自動でテストしてくれます

test.pyで試してみましょう!

accounts > test.py

from django.test import TestCase

from django.contrib.auth import get_user_model
from accounts.models import Profile

User = get_user_model()

class AccountsTestCase(TestCase):
    def __init__(self, *args, **kwargs):
        self.email = "test@itc.tokyo"
        self.password = "somepassword"
        super().__init__(*args, **kwargs)

    def setUp(self):
        user_obj = User(email=self.email)
        user_obj.set_password(self.password)
        user_obj.save()

    def test_profile_saved(self):
        counter = Profile.objects.count()
        self.assertEqual(counter, 1)
        profile_obj = Profile.objects.first()
        self.assertEqual(profile_obj.user.email, profile_obj.username)

setUp関数ではUserオブジェクトを一つ保存しています

先程のpost_saveメソッドが正しく動作していれば、Userオブジェクト作成後に自動的にProfileも作成されているはずですね

test_profile_saved関数で、Profileオブジェクトが一つ存在しているかどうかと、ユーザーのemailアドレスとユーザー名が一緒かどうかを確認するよう記述しています

実行、確認

ターミナルで

$ python manage.py test accounts

を実行してみましょう!

エラーが出なければsignalsの作成は成功です!!

まとめ

当記事を通じて、

  • modes.pyにシグナル「post_save」を使用したProfileを自動的に作成するコードを記述
  • test.pyで自動テストを実行する関数

を定義しました

ただし、このままだとユーザー名がEmailアドレスになっているので、結局Eメールアドレスが公開されてしまいます

あくまでもEメールアドレスは仮のusernameです

次回は、usernameがEメールアドレスとなっている状態でログインした際には、アカウント設定ページへ、それ以外は通常のLOGIN REDIRECTで指定したページへリダイレクトするよう、ログイン後のリダイレクトを動的に変更する方法をお伝えします

django-allauthのDefaultAdapterを使った方法になりますので、ここで覚えておくと色々と応用も聞きますのでお楽しみに!

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