3-3. LoginViewを使用してログイン画面を作成する

今回のテーマは「LoginViewを使用してログイン画面を作成する」です。前回まではビューを自作していましたが、今回はDjangoに組み込まれたLoginViewを用いてログイン機能を構築していきます。3章の初めでも書きましたが、ログイン機能はテンプレートを作るだけでスピーディに実現できます。

※本ページは「ユーザープロフィール画面を作成する」まで読まれた方を対象としています。そのためサンプルソースコードが省略されている場合があります。

django.contrib.auth.urlsをインクルードする

Djangoの認証用のビューを使用する際のURLの設定で最も簡単なのはプロジェクト用のurls.py(今回のケースだとmysite/urls.py)にdjango.contrib.auth.urlsのurlpatternsをインクルードすることです。具体的にはmysite/urls.pyを以下のように変更します。


  urlpatterns = [
      path('admin/', admin.site.urls),
+     path('accounts/', include('django.contrib.auth.urls')),
      path('accounts/', include('accounts.urls')),
      path('', include('base.urls')),
      path('thread/', include('thread.urls')),
      path('api/', include('api.urls')),
      path('search/', include('search.urls')),
      path('sitemap.xml', sitemap, {'sitemaps': sitemaps}),
  ] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)

ではここでdjango.contrib.auth.urlsのurlpatternsの中身を見てみましょう。

django/contrib/auth/urls.py(一部抜粋)


from django.contrib.auth import views
from django.urls import path

urlpatterns = [
    path('login/', views.LoginView.as_view(), name='login'),
    path('logout/', views.LogoutView.as_view(), name='logout'),

    path('password_change/', views.PasswordChangeView.as_view(), name='password_change'),
    path('password_change/done/', views.PasswordChangeDoneView.as_view(), name='password_change_done'),

    path('password_reset/', views.PasswordResetView.as_view(), name='password_reset'),
    path('password_reset/done/', views.PasswordResetDoneView.as_view(), name='password_reset_done'),
    path('reset///', views.PasswordResetConfirmView.as_view(), name='password_reset_confirm'),
    path('reset/done/', views.PasswordResetCompleteView.as_view(), name='password_reset_complete'),
]

このurlspatternsをmysite/urls.pyにインクルードすることで以下のように各URLで各ビューにアクセスすることにあります。

/accounts/login/ -> LoginView ログイン機能
/accounts/logout/ -> LogoutView ログアウト機能
/accounts/password_change/ -> PasswordChangeView パスワード変更機能
/accounts/password_reset/ -> PasswordResetView パスワードリセット機能
※他は省略

テンプレートの作成

今回はビューに関しては組込みのLoginViewを使用するのでテンプレートを作成しましょう。registration/login.htmlを作成します。さて、ここで何故templatesディレクトリ内にaccountsディレクトリではなくregistrationディレクトリを作成したか説明します。LoginViewのクラス変数であるtemplate_nameのデフォルト値は’registration/login.html’なのです。他のLogoutViewのテンプレートのデフォルト値は’registration/logout.html’であり、他も同様です。よって統一するためにURLが/accounts/でアクセスするビューに関してはregistrationに統一しました。

templates/registration/login.html



{% extends 'base/base.html' %}
{% block title %}ITについて切磋琢磨する掲示板 - {{ block.super }}{% endblock %}
{% block content %}
<div class="ui grid stackable">
    <div class="eleven wide column">
        <div class="ui breadcrumb">
            <a href="{% url 'base:top' %}" class="section">TOP</a>
            <i class="right angle icon divider"></i>
            <a class="active section">ログイン</a>
        </div>
        <div class="ui segment">
            <div class="content">
                <div class="header"><h3>ログイン</h3></div>
                <form class="ui form" action="" method="POST">
                    {% csrf_token %}
                    {{form.as_p}}
                    <button class="ui orange button" type="submit">ログイン</button>
                </form>
            </div>
        </div>
        <a class="ui item" href="{% url 'accounts:create' %}">ユーザー登録</a>/
        <a class="ui item" href="{% url 'password_reset' %}">パスワードを忘れた場合</a>
    </div>
    {% include 'base/sidebar.html' %}
</div>
{% endblock %}

それでは画面のヘッダーのURLも修正しておきましょう。
templates/registration/login.html



    <div class="ui stackable inverted menu">
        <a href="{% url 'base:top' %}" class="header item">
            IT学習ちゃんねる
        </a>
        <a href="{% url 'base:about' %}" class="item">
            このサイトはなに?
        </a>
        <a class="item" href="{% url 'thread:create_topic' %}">
            トピック作成
        </a>
        <div class="right menu">
            {% if user.is_authenticated %}
            <a class="item" href="{% url 'accounts:profile' %}">ユーザー情報</a>
            <a class="item" href="">ログアウト</a>
            {% else %}
-           <a class="item" href="">ログイン</a>
+           <a class="item" href="{% url 'login' %}">ログイン</a>
            <a class="item" href="{% url 'accounts:create' %}">ユーザー登録</a>
            {% endif %}
        </div>
    </div>


ログイン画面へのURLに関して”{% url ‘login’ %}”ですね。’accounts:login’ではないことに注意して下さい。django/contrib/auth/urls.pyではapp_nameを設定していないので、このURLのショートカットは’login’となります。

では掲示板にアクセスして確認してみましょう。localhost:8080/accounts/login/にアクセスしてログイン画面から作成したユーザーでログインできればOKです。

ログイン後の遷移先は?

さて、無事ユーザー情報ページに遷移しましたか?ところで1つの疑問が湧きます。なぜユーザー情報ページに遷移したのでしょうか?LoginViewはGETもしはPOSTで遷移先のURLが与えられた場合はそのURLに遷移し、特に指定がなければsettings.LOGIN_REDIRECT_URLに遷移します。このLOGIN_REDIRECT_URLのデフォルト値は’/accounts/profile/’なのです。よって先に作成しておいたユーザー情報ページに遷移シました。尚、GET/POSTでURLを与える時はパラメータのキーはデフォルトで”next”です。これはLoginViewのクラス変数であるredirect_field_nameで変更できます。

最後に

今回はLoginViewを中心に見てきました。次回はログアウト処理を見ていきます。

コメントを残す

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