【Django】クラスベースビューの補足:LoginViewの見えない処理と仕組みについて

概要

以下のLoginViewを使用したログイン処理について、見えない親クラスの処理をざっくりと見える化して全体のどこの処理をオーバーライドしているのかをまとめた。

あわせて読みたい

概要 クラスベースビュー(class-based view)でログイン機能を作成したのでまとめた。 ログイン機能は、Djangoがもともと用意しているLoginViewクラスを使用する。 LoginViewの場合、ListViewのよ[…]

 

LoginView

Djangoがもともと用意しているLoginViewはオーバーライドして実装する必要がない。

そのため、見えない処理だらけで余計にややこしいクラスベースビューになる。

GETリクエストの処理概要

細かい内容は割愛して、大きな処理の流れは以下となる。

▲GET処理の流れ

解説

それぞれの処理について解説する。

全体的な流れ

画面に渡すフォームを取得する。
フォームは画面とサーバー間でデータの受け渡しをするための「箱」というイメージ。
フォームの箱をコンテキストに設定して、画面テンプレートとコンテキストを組み合わせたHTMLをレスポンスとして返却する。

 

dispatch()メソッド

ブラウザからのリクエストをもとに、get()メソッドまたはpost()メソッドの呼び出しを制御する。
今回はget()メソッドを呼び出す。

 

コンテキスト設定

get_formを呼び出し、空のAuthenticationFormインスタンスを生成する。
LoginViewではデフォルトでフォーム名(form_class)にAuthenticationFormを設定している。
生成した空のフォームインスタンスをコンテキストに設定している。

 

レスポンス返却

コンテキストと”registration/login.html”を組み合わせた画面を返却する。
LoginViewではデフォルトでテンプレート名(template_name)に”registration/login.html”を指定している。
そのため、上記パスのHTMLファイルを作成することで、ログイン画面を表示することができる。

 

POSTリクエストの処理概要

細かい内容は割愛して、大きな処理の流れは以下となる。

▲POST処理の流れ

解説

それぞれの処理について解説する。

全体的な流れ

画面入力値を保持したフォームインスタンスを取得する。
フォームインスタンス内で入力チェックを行う。
エラー有の場合:
エラー情報を保持したフォームをコンテキストに設定する。
コンテキストと”registration/login.html”を組み合わせた画面を返却する。
エラー無の場合:
メイン処理(今回はログイン処理)を行う。
メイン処理完了後、処理成功URLにリダイレクトする。

 

dispatch()メソッド

ブラウザからのリクエストをもとに、get()メソッドまたはpost()メソッドの呼び出しを制御する。
今回はpost()メソッドを呼び出す。

 

画面入力値取得

画面入力値を保持したAuthenticationFormインスタンスを取得する。

 

入力チェック

AuthenticationFormインスタンス内で入力チェックを行う。
DBにログイン利用者の情報が存在するかを参照する処理も行う。
エラーがある場合、インスタンス内にてエラー情報を保持する。

 

エラー処理

入力チェックエラーとなった場合に呼ばれる。
コンテキストを設定する処理を呼び出し、レスポンスを返却する処理を呼び出す。

 

コンテキスト設定

エラー情報を保持したフォームインスタンスをコンテキストに設定する。

 

レスポンス返却

コンテキストと”registration/login.html”を組み合わせた画面を返却する。
テンプレート(HTML)側にエラー表示領域を定義することで、エラーメッセージを表示できる。

 

メイン処理

ログイン処理を呼び出して、セッションにログイン情報を登録する。
その後、settings.pyに定義されたURLへリダイレクトする。
※LoginViewはsettings.pyにLOGIN_REDIRECT_URLが定義されている場合、そこからURLを取得する

 

処理の補足

ログイン処理が何を何をやっているのか、またログイン成功時の動きはどうなっているのかについて補足する。

ログイン処理

LoginViewのログイン処理は以下のように記述されている。

django.contrib.auth.views.LoginView


def form_valid(self, form):
    """Security check complete. Log the user in."""
    auth_login(self.request, form.get_user())
    return HttpResponseRedirect(self.get_success_url())
 

auth_loginメソッドを呼び出してログイン者情報をセッションに登録している。
また、request.userに利用者情報を設定しているのも上記メソッドになる。

 

ログイン成功時のリダイレクト

ログイン成功時のリダイレクトは以下のように記述されている。

django.contrib.auth.views.LoginView


def get_default_redirect_url(self):
    """Return the default redirect URL."""
    if self.next_page:
        return resolve_url(self.next_page)
    else:
        return resolve_url(settings.LOGIN_REDIRECT_URL)

LoginViewのsuccess_urlはデフォルトで定義されておらず、next_pageパラメータが存在しない場合はsetteings.pyのLOGIN_REDIRECT_URLを参照する。

settings.py

以下のようにsettings.pyの定数名にリダイレクトさせたいビュー名を指定することで、ログイン成功後のリダイレクト先を指定できる。

settings.py


LOGIN_REDIRECT_URL = "top"

 

next_pageの設定

next_pageにログイン成功時のリダイレクト先を指定したい場合、以下のようにLoginViewクラスを継承してフィールド名next_pageにリダイレクト先のビュー名を設定する必要がある。

accounts.views.py


class TodoLoginView(LoginView):
    """ログインビューを実装してみた"""

    # 次画面遷移フィールド
    next_page = "top"
 

accounts.urls.py


from django.urls import path
from . import views
from django.contrib.auth.views import LoginView, LogoutView

urlpatterns = [
    path("login/", views.TodoLoginView.as_view(), name="login"),
    path("signup/", views.SignupView.as_view(), name="signup"),
    path("logout/", LogoutView.as_view(), name="logout"),
]

 

スポンサーリンク