Django でログインページを作る
Python のフルスタックWebフレームワークとして有名な Django を使ってログインページを簡単に作ってみます。
準備
雛形の生成
Django のプロジェクトをセットアップします。
$ mkdir myapp $ cd myapp $ django-admin startproject config . $ python manage.py startapp myauth $ python manage.py startapp appmain $ python manage.py makemigrations $ python manage.py migrate $ python manage.py createsuperuser # ユーザー名とパスワードを設定する
これらを実行することで以下のようなディレクトリ構成が得られます。
$ tree -L 2 . ├── appmain # 内部ページ │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ ├── models.py │ ├── tests.py │ ├── views.py ├── config # プロジェクト全体の設定 │ ├── __init__.py │ ├── asgi.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── db.sqlite3 ├── manage.py └── myauth # 今回ログインページをつくるところ ├── __init__.py ├── admin.py ├── apps.py ├── migrations ├── models.py ├── tests.py └── views.py
基本的な設定
config/settings.py
# ... LOGIN_REDIRECT_URL = "/" # ログイン後にどこに飛ばすか LOGIN_URL = "/myauth" # ログインページの URLを設定 # ... INSTALLED_APPS = [ "myauth.apps.MyauthConfig", # <- 追加 "appmain.apps.AppmainConfig", # <- 追加 "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", ] # ...
config/urls.py
from django.contrib import admin from django.urls import path, include urlpatterns = [ path("admin/", admin.site.urls), path("", include("appmain.urls")), path("myauth/", include("myauth.urls")), ]
appmain/urls.py
from django.urls import path from appmain import views urlpatterns = [path("", views.index, name="index")]
myauth/urls.py
from django.urls import path from myauth import views app_name = "myauth" urlpatterns = [path("", views.Login.as_view(), name="login")]
内部ページの実装
ログインしたあとに飛ぶページを作ります。これは今回の主題ではないので簡単に作ります。上の appmain/urls.py に設定したように、ルートページとして views.index
を表示するようにしているので、これを作ります。
appmain/views.py
from django.shortcuts import render from django.contrib.auth.decorators import login_required @login_required def index(request): return render(request, "appmain/index.html")
呼ばれたら index.html を表示するだけです。シンプルですね。
appmain/templates/appmain/index.html
<html> <head></head> <body>This is inner page</body> </html>
Django では HTML ファイルは慣習的に (app名)/templates/(app名)/ ディレクトリに入れるということになっていますので少しパス名が長くなります。
ログインページの実装
まずはログイン情報を入力するフォームを作ります。
myauth/forms.py
from django.contrib.auth.forms import AuthenticationForm class LoginForm(AuthenticationForm): def __init__(self, *args, **kwargs): super(LoginForm, self).__init__(*args, **kwargs)
Django には認証用のフォームを作るためのクラスが用意されているのでそれを継承すれば良いです。このフォームをビューに組み込みます。
myauth/views.py
from django.contrib.auth.views import LoginView from myauth.forms import LoginForm class Login(LoginView): form_class = LoginForm template_name = "myauth/index.html"
これでログインページの実装は9割方終わりです。あとは HTML ファイルを作ります。
myauth/templates/myauth/index.html
<html> <head> <title>Login Page</title> </head> <body> <h2>Login</h2> <form method="post" action="{% url 'myauth:login' %}"> {% csrf_token %} {{ form.username }} {{ form.password }} {% if form.errors %} <p>ユーザー名またはパスワードが一致しません</p> {% endif %} <input type="submit" value="login"/> </form> </body> </html>
ビューの中でフォームを取り込んでいるので、HTML内では LoginForm
の持つ変数を使うことができます。この記事では明示的にフォーム内で変数を定義することはしていませんが、AuthenticationForm
が username
とpassword
を定義しているのでそれを HTML 内で {{ form.username }}
のようにして使うことができます。
フォームのアクションとして myauth:login
を指定しています。これは「myauth」という名前空間内の「login」というビューにフォームの内容を送信するということを指定しています。「myauth」の urls.py 内を見直してみると
path("", views.Login.as_view(), name="login")
という記述があります。myauth:login
の login
は、この name="login"
を指しています。
実行してみる
では、今まで実装してきたコードを試してみます。
$ python manage.py runserver
として http://localhost:8000/myauth
にアクセスしてみます。
CSS は何も書いていないので非常にシンプルですがきちんとログインページが出来ています。一番最初に管理者としてユーザーを1人登録していますのでそのユーザーのユーザー名とパスワードを入力すれば内部ページに飛べます。間違っていれば ユーザー名またはパスワードが一致しません
という文字が表示されるはずです。