Djangoでログイン・ログアウト・ユーザー登録を行う

Djangoでログイン・ログアウト・ユーザー登録処理を実装する手順を紹介します。

本記事ではDjangoの「デフォルトのユーザーモデル」を利用してユーザー登録を行いますが、Djangoではユーザーモデルをカスタマイズすることもできます。

カスタマイズしたユーザーモデルを使って、ログイン・ログアウト・ユーザー登録の処理を行うこともできるのです。

ユーザーモデルをカスタマイズする方法は以下の記事で紹介しています。

Django|カスタムユーザーモデルの作り方(AbstractUserを使ったサンプル)

ユーザー登録を行う

ユーザー登録用のDjangoアプリケーションを作成します。

% python manage.py startapp accounts

上記で作成したアプリケーションをDjangoプロジェクトにインストールするために、blogexample/settings.pyのINSTALLED_APPSを編集します。

ここでの「blogexample」というのは、$ django-admin startproject blogexampleで作成されたDjangoプロジェクトのことです。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'blog.apps.BlogConfig',
    'accounts.apps.AccountsConfig', # new
]

次に、blogexample/urls.pyを編集して、accountsアプリケーションのurls.pyを読み込むように定義します。

from django.contrib import admin
from django.urls import path, include # new

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', include('blog.urls')),
    path('accounts', include('django.contrib.auth.urls')),
    path('accounts', include('accounts.urls')),
]

path('accounts', include('django.contrib.auth.urls'))のように、django.contrib.auth.urlsを読み込んでいますが、それによって以下のようなURLパターンが自動的に組み込まれます。

accounts/login/ [name='login']
accounts/logout/ [name='logout']
accounts/password_change/ [name='password_change']
accounts/password_change/done/ [name='password_change_done']
accounts/password_reset/ [name='password_reset']
accounts/password_reset/done/ [name='password_reset_done']
accounts/reset/<uidb64>/<token>/ [name='password_reset_confirm']
accounts/reset/done/ [name='password_reset_complete']

詳細はDjangoの公式ドキュメントを参照してください。

参考 Using the Django authentication systemDjango公式ドキュメント

GitHubのauth.urls.pyを見るとurlpatternsがどう定義されているかがわかりやすいです。

次にaccounts/urls.pyを作成し、以下のようにURLパターンを定義します。

from django.urls import path

from .views import SignUpView

urlpatterns = [
  path('signup/', SignUpView.as_view(), name='singup')
]

次にビューを作ります。
accounts/views.pyにUserCreationFormを追加しましょう。

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

class SignUpView(generic.CreateView):
  form_class = UserCreationForm
  success_url = reverse_lazy('login')
  template_name = 'signup.html'

次にテンプレートを作成します。
templates/signup.htmlを作りましょう。

<h2>ユーザー登録</h2>
<form method="post">
  {% csrf_token %}
  {{ form.as_p }}
  <button type="submit">登録</button>
</form>

テンプレートの作成方法は以下の記事を参考にしてください。

DjangoでTemplates(テンプレート)を作成してHTMLを表示する

http://127.0.0.1:8000/accounts/signup/にアクセスすると、以下のような画面が表示されます。

とりあえず、

ユーザー名:Abehiroshi55
パスワード:Kimuratakuya50sai

で登録してみます。

管理者画面で確認してみると、以下のようにユーザーの登録ができていることがわかります。

まだログインテンプレートを作っていないので、この時点で登録するとTemplateDoesNotExist at /accounts/login/というエラーが出ます。
ユーザー登録はできます。

ログイン機能を実装する

ここからはテンプレートをtemplates/registration以下に作成していきましょう。
上で作成したsignup.htmlもregistrationに移します。

blogexample/settings.pyのTEMPLATESを編集します。
変更したのは'DIRS': [os.path.join(BASE_DIR, 'templates'), os.path.join(BASE_DIR, 'templates/registration')],の部分です。
regstrationディレクトリを見に行くようにしました。


TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates'), os.path.join(BASE_DIR, 'templates/registration')],
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

次にログイン後に移動するURLをsettings.pyに定義します。
blogexample/settings.pyの一番下にLOGIN_REDIRECT_URLを追加してください。


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/

STATIC_URL = '/static/'

LOGIN_REDIRECT_URL = 'home'

次にログインフォームのテンプレートを作ります。
templates/registration/login.htmlに以下のように書きます。

<h2>ログイン</h2>
<form method="post">
  {% csrf_token %}
  {{ form.as_p }}
  <button type="submit">ログイン</button>
</form>

http://127.0.0.1:8000/accounts/login/にアクセスすると、ログイン画面が表示されます。

ユーザー登録したユーザー名とパスワードを入力するとログインできます。

ホーム画面でログインしているユーザー名を表示させるようにしてみましょう。

templates/home.htmlを以下のように書きます。


<h2>ホーム画面</h2>
<p>
  {% if user.is_authenticated %}
    <em>{{ user.username }}でログインしています。</em>
  {% else %}
    <em>まだログインしていません。</em><br/>
    ログインは<a href="{% url 'login' %}">こちら</a>
  {% endif %}
</p>

{% for post in object_list %}
<div class="post">
  <h2>詳細へ:<a href="{% url 'blog_detail' post.pk %}">{{ post.title }}</a></h2>
  <p>{{ post.body }}</p>
  <h2>編集:<a href="{% url 'blog_edit' post.pk %}">{{ post.title }}</a></h2>
  <h2>削除:<a href="{% url 'blog_delete' post.pk %}">{{ post.title }}</a></h2>
</div>
{% endfor %}

ホーム画面を開くと、以下のようにログインしているユーザー名が表示されます。

ちなみに上の「ホーム画面」ではテンプレート内でuser.usernameuser.authenticatedが自動的に使えるようになっていました。
これはDjangoの template_context と呼ばれる機能によるもので、それぞれのテンプレートが呼び出されるときに、userやpermissionのデータが読み込まれる仕組みになっているからです。

参考 Using the Django authentication systemDjango公式ドキュメント

ログアウト機能を実装する

blogexample/settings.pyにLOGOUT_REDIRECT_URL変数を追加します。

# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/

STATIC_URL = '/static/'

LOGIN_REDIRECT_URL = 'home'
LOGOUT_REDIRECT_URL = 'home'

ホームページにログアウト用のリンクを追加します。{% url 'logout %}を追加すればOKです。

templates/home.htmlは以下のようになります。


<h2>ホーム画面</h2>
<p>
  {% if user.is_authenticated %}
    <em>{{ user.username }}でログインしています。</em><br/>
    ログアウトするなら→<a href="{% url 'logout' %}">ログアウト!</a>
  {% else %}
    <em>まだログインしていません。</em><br/>
    ログインは<a href="{% url 'login' %}">こちら</a>
  {% endif %}
</p>

{% for post in object_list %}
<div class="post">
  <h2>詳細へ:<a href="{% url 'blog_detail' post.pk %}">{{ post.title }}</a></h2>
  <p>{{ post.body }}</p>
  <h2>編集:<a href="{% url 'blog_edit' post.pk %}">{{ post.title }}</a></h2>
  <h2>削除:<a href="{% url 'blog_delete' post.pk %}">{{ post.title }}</a></h2>
</div>
{% endfor %}

ログアウトリンクをクリックすると、ログアウトすることができます。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です