17.Djangoアプリにサインアップ機能を実装しよう

Djangoアプリにユーザー登録のためのサインアップ機能を実装してみましょう。Djangoが予め用意してくれている汎用ビューやUserモデルを使えば、簡単にサインアップ機能を実装することができます。

今回は独自のモデルは作らずに、最も簡単なユーザー名とパスワードだけでサインアップする機能を実装してみましょう。

目次

ユーザー管理アプリの作成・登録

まずはユーザー管理用のアプリケーションを作成します。

Windows PowerShell で django-tutorial へ移動し、次のコマンドでアプリケーション用のファイルを自動生成します。

python manage.py startapp accounts

このアプリをDjangoプロジェクトに登録しておきましょう。

config/settings.py に次のように記述します。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'hello.apps.HelloConfig',
    'bbs.apps.BbsConfig',
    'accounts.apps.AccountsConfig', # 作成したアプリを追加
]

これで先ほど作成した accounts アプリケーションをDjangoが認識できるようになりました。

ルーティングの設定

accounts アプリのルーティングを設定します。

/config/urls.py に次のように記述します。

from django.contrib import admin
from django.urls import path, include
from django.views.generic import RedirectView

urlpatterns = [
    path('admin/', admin.site.urls),
    path('hello/', include('hello.urls')),
    path('bbs/', include('bbs.urls')),
    path('accounts/', include('accounts.urls')), # accounts/以下のルーティングはaccounts.urls.pyに任せる
    path('accounts/', include('django.contrib.auth.urls')),
    path('', RedirectView.as_view(url='/bbs/')),
]

前回のログイン機能のルーティングも accounts/ だったので、このルートが2つありますが、こういう場合Djangoは上から順番に調べます。

今回の場合、まず accounts.urls.py に一致するパスがないか探して、一致するものがなければ後述されている django.contrib.auth.urls を探してくれます。

accounts/以下のルーティングも設定しましょう。

先ほど生成した accounts ディレクトリの中に urls.py というファイルを作成し、次のように記述します。

from django.urls import path
from . import views

app_name = 'accounts'

urlpatterns = [
    path('signup/', views.SignUpView.as_view(), name='signup'), # ユーザー登録を呼び出すビュー
]

サインアップ画面のビューとして SignUpView というクラスからビュー関数化したものを指定しました。

ビューの作成

先ほど指定した SignUpView クラスを作成しましょう。

/accounts/views.py に次のように記述します。

from django.contrib.auth.forms import UserCreationForm
from django.urls import reverse_lazy
from django.views import generic

# 汎用ビューのCreateViewを継承したSignUpViewクラスを作成
class SignUpView(generic.CreateView):
    form_class = UserCreationForm
    success_url = reverse_lazy('login')
    template_name = 'accounts/signup.html'

ユーザー情報を登録するために汎用ビューの CreateViewクラスを継承して SignUpViewクラスを作成。

その中で UserCreationForm を呼び出し、テンプレートとして accounts/signup.html を呼び出します。

そしてサインアップ成功時にはログインページのURL(/login/)にリダイレクトします。

テンプレートを作成

次は呼び出すテンプレートを作成します。

templatesディレクトリの中にaccountsディレクトリを作成し、その中にsignup.htmlという名前でファイルを作成します。

templatesディレクトリの中にaccountsディレクトリを作成

signup.html に次のように記述します。

{% extends 'base.html' %}

{% block content %}
<h1>Sign up</h1>
<section>
    <form method='post'>
        {% csrf_token %}
        {{ form.as_p }}<!-- 汎用ビューで用意した項目をフォームとして表示 -->
        <button type='submit'>サインアップ</button>
    </form>
</section>
{% endblock %}

共通テンプレートですが、ログイン画面のものと共通にしてしまいましょう。

アプリケーションをまたいだ、プロジェクト全体の共通テンプレートはtemplatesディレクトリの直下に配置します。

プロジェクト全体の共通テンプレートの配置

<!DOCTYPE html>
<html lang="ja">
  <head>
    <meta charset="utf-8">
    <title>Djangoのユーザー管理機能を使ってみよう!</title>
    <style>h1 {color: #0000ff}</style>
  </head>
  <body>
    {% block content %}
    {% endblock %}
  </body>
</html>

このテンプレートを呼び出すときは次のように区切り文字を入れずに指定します。

{% extends 'base.html' %}

後略

ログイン画面(login.html)とログアウト画面(logged_out)のテンプレートも、こちらの共通テンプレートを呼び出すよう修正しておきましょう。

サインアップ画面へのリンクを配置

サインアップ画面へのリンクを配置しておきましょう。

login.html に次のように追記します。

{% extends 'base.html' %}

{% block content %}
<h1>Djangoで作るログイン機能</h1>
{% if user.is_authenticated %}<!-- ユーザーを認証していたら -->
  <p>{{ user }} でログインしています</p>
  <button onclick='location.href="{% url "logout" %}"'>ログアウト</button>
{% else %}
  <section>
    <!-- ログイン用フォーム -->
    <form action='{% url "login" %}' method='post'>
      {% csrf_token %}
      <input type='hidden' name='next' value='{{ next }}'/><!-- csrf_token用の隠し項目 -->
      {{ form.as_p }}<!-- ログイン用の項目 -->
      <button type='submit'>ログイン</button>
    </form>
    <button onclick='location.href="{% url "accounts:signup" %}"'>新規登録</button>
  </section>
{% endif %}
{% endblock %}

ユーザーがログインしていない時に、ログインフォームのほかに「新規登録」ボタンも配置しています。

これならログイン画面にアクセスしたユーザーがまだユーザー登録をしていなかったとしても、迷わずサインアップ画面に進むことができます。

動作確認

それでは動作確認です。

Djangoコマンドを使ってサーバーを起動し、ブラウザで確認してみましょう。

http://127.0.0.1:8000/accounts/login/ にアクセスします。

ログインページ

ログインボタンの下に「新規登録」ボタンが表示されています。クリックしてみましょう。

サインアップ画面

サインアップ画面が表示されました。

実際にユーザー登録してみましょう。必要項目を入力して「サインアップ」ボタンをクリックします。

サインアップが完了し、ログイン画面にリダイレクトされました。

先ほど登録したユーザー名とパスワードでログインしてみましょう。

サインアップ完了

ログイン成功

ログインが完了し、投稿一覧ページにリダイレクトされました。

登録されたユーザーデータを確認してみましょう。

Djangoの管理サイト(http://127.0.0.1:8000/admin/)にアクセスします。

Djangoの管理サイト

管理者権限のあるスーパーユーザーでログイン。

「ユーザー」をクリック

「ユーザー」をクリックしてデータベースを確認してみましょう。

保存されたユーザー情報の確認

先ほど登録した「onishi」というユーザーが保存されています。

このようにサインアップ機能で登録したユーザー情報はDjangoのUserモデルに対応するテーブルに保存されます。

このエントリーをはてなブックマークに追加

コメントを残す

頂いたコメントは一読した後表示させて頂いております。
反映まで数日かかる場合もございますがご了承下さい。