Edited at

【Django】DjangoによるWeb開発プロジェクトPart2 - ログインページを作成する所まで -


はじめに

前回の内容から大分、間が空いてしまいましたがDjangoによるWeb開発を進めていきたいと思います。

今回はDjangoにログイン認証の画面を作成する所までを進めていきたいと思います。


アプリケーションを作成する

DjangoではTOPディレクトリに作成したプロジェクトの配下となるアプリケーションを作成する事で、独立した操作を行えるアプリケーションを作成する事ができます。プロジェクトはそのアプリケーションを一つにまとめたものです。

サブモジュールとしてsample_project/作成するアプリケーション名とすることもできますが、今回はTOPディレクトリに置くことにします。

アプリケーションを作成するには、 manage.py と同じディレクトリに入って、以下のコマンドを実行します。

% python manage.py startapp polls

pollsのディレクトリ構成は以下のようになります。

% ls -al polls

total 21
drwxr-xr-x 3 himrock922 himrock922 9 11月 4 18:18 .
drwxr-xr-x 6 himrock922 himrock922 12 11月 4 18:18 ..
-rw-r--r-- 1 himrock922 himrock922 0 11月 4 18:18 __init__.py
-rw-r--r-- 1 himrock922 himrock922 63 11月 4 18:18 admin.py
-rw-r--r-- 1 himrock922 himrock922 91 11月 4 18:18 apps.py
drwxr-xr-x 2 himrock922 himrock922 3 11月 4 18:18 migrations
-rw-r--r-- 1 himrock922 himrock922 57 11月 4 18:18 models.py
-rw-r--r-- 1 himrock922 himrock922 60 11月 4 18:18 tests.py
-rw-r--r-- 1 himrock922 himrock922 63 11月 4 18:18 views.py


viewの作成

Djangoで最も単純なビューページを書いていきます。


polls/views.py

from django.http import HttpResponse

def index(request):
return HttpResponse("Hello, world. You're at the polls index.")


単純な文字出力を行うviewを呼ぶために、URLに対応づけしてあげる必要があります。

そのためには、URLconf が必要となります。


polls/urls.py

from django.urls import path

from . import views

urlpatterns = [
path('', views.index, name='index'),
]


views.pyのindexメソッドを呼び出し、パス名をindexとして、紐付けさせます。

次に、ルートのURLConfにaccounts.urlsモジュールを読み込ませます。

from django.contrib import admin

from django.urls import include, path

urlpatterns = [
path('polls/', include('polls.urls')),
path('admin/', admin.site.urls),
]

include()関数は他のURLConfへの参照をする事ができます。

以上で簡単なURLのPathを作成する事ができました。

この内容に沿った形でログイン認証を行うページを作ろうと思ったのですが、実は既にDjangoには認証システムが用意されています。


Djangoの認証システムを使ってログイン認証システムを作る

Djangoの認証システムを使用する

こちらにきめ細かな仕様が載っているのですが、情報量が多すぎるので読むのが少し大変でした汗。ひとまず、認証を実現する機能として必要なメソッドやモデルが既に用意されているdjango.contrib.authがあるのでstartappで作る必要がない模様です。

これだけだと、分かりにくかったのでもう一つ参考文献を。

Django Login/Logout Tutorial (Part 1)

認証用のviewは実装されているが対応するテンプレートはサポートしていないため、各自で実装すること、またサインアップのメソッドは用意されていないため、こちらも各自で書く必要があります。いずれにせよ、startappでアプリケーションを作成する必要がないので、上のDjango Login/Logout Tutorial (Part 1)を参考にログイン認証を作っていきます。

% rm -rf polls


Auth App

Djangoプロジェクトを構築した時に自動的にauth アプリケーションがインストールされています。


settings.py

INSTALLED_APPS = [

'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
]

authアプリケーションを使うために、urls.pyにaccounts配下のパスとauth.urlsのパターンを紐付けさせます。


urls.py

from django.contrib import admin

from django.urls import include, path

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


authアプリケーションをincludeすると、以下の認証ビューが提供されます。

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']

ついでにこの際時刻設定と日本語設定、およびsqlite3からpostgresqlを使う様に設定します。

% sudo pkg install postgresql10-server-10.5 postgresql10-contrib-10.5

% sudo vim /etc/login.conf
postgres:\
:lang=en_US.UTF-8:\
:setenv=LC_COLLATE=C:\
:tc=default:
% sudo vim /etc/rc.conf
postgresql_class="postgres"
postgresql_enable="YES"

% sudo service postgresql initdb
% sudo service postgresql start

$ sudo su - postgres

$ createdb mydb
$ createuser -P
$ psql
$ GRANT ALL PRIVILEGES ON DATABASE mydb TO myuser;

% pip install psycopg2


settings.py


DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'mydb',
'USER': 'myuser',
'PASSWORD': 'mypass',
'HOST': 'localhost',
'PORT': '',
}
}

(中略)
LANGUAGE_CODE = 'ja'

TIME_ZONE = 'Asia/Tokyo'



ログインページを作成する

ログインページを作ります。authはデフォルトでregistration配下のテンプレートフォルダを読み込みます。registrationディレクトリを作成し、loginテンプレートとしてlogin.htmlを作成します。

% mkdir -p templates/registration


templates/registration/login.html

<h2>Login</h2>

<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Login</button>
</form>

{% csrf_token %}でCSRFトークンを発行でき、{{ form.as_p }}`でログインフォームを作成できます。

続いてDjangoがtemplatesディレクトリを見つけられるように、settings.pyを修正します。

また、ログイン成功後のリダイレクトページを指定するためにLOGIN_REDIRECT_URLを追加します。


settings.py

TEMPLATES = [

{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')],
'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',
],
},
},
]
LOGIN_REDIRECT_URL = '/'

ユーザーを作成後、Djangoを再起動すると http://127.0.0.1:8080/accounts/login においてログインページが表示されます。

スクリーンショット 2018-11-18 22.49.35.png

ログインできるようにユーザー作成を行いましょう。

% python3.7 manage.py migrate                                           (git)-[feature/add_login]

Operations to perform:
Apply all migrations: admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying auth.0001_initial... OK
Applying admin.0001_initial... OK
Applying admin.0002_logentry_remove_auto_add... OK
Applying admin.0003_logentry_add_action_flag_choices... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0002_alter_permission_name_max_length... OK
Applying auth.0003_alter_user_email_max_length... OK
Applying auth.0004_alter_user_username_opts... OK
Applying auth.0005_alter_user_last_login_null... OK
Applying auth.0006_require_contenttypes_0002... OK
Applying auth.0007_alter_validators_add_error_messages... OK
Applying auth.0008_alter_user_username_max_length... OK
Applying auth.0009_alter_user_last_name_max_length... OK
Applying sessions.0001_initial... OK
% python manage.py createsuperuser
ユーザー名 (leave blank to use '*********'):
メールアドレス: ********
Password:
Password (again):
Superuser created successfully.

以上で、作成したユーザーでログインする事ができるのですが、ログイン成功後のリダイレクトページをまだ作っていないため、レスポンスは404が返ってきます。

スクリーンショット 2018-11-18 22.54.20.png

次にindexのページを作ってあげましょう。


indexページの作成

indexのページと全ページ共通のrenderページとしてapplication.htmlを作成します。


templates/application.html

<!DOCTYPE html>

<html lang="ja">
<head>
<meta charset="utf-8">
<title>{% block title %}Django Auth Tutorial{% endblock %}</title>
</head>
<body>
<main>
{% block content %}
{% endblock %}
</main>
</body>
</html>


templates/index.html

{% extends 'application.html' %}

{% block title %}Home{% endblock %}

{% block content %}
{% if user.is_authenticated %}
Hi {{ user.username }}!
{% else %}
<p>You are not logged in</p>
<a href="{% url 'login' %}">login</a>
{% endif %}
{% endblock %}


また、それに伴いlogin.htmlをapplication.htmlを読み込むように修正します。


templates/registration/login.html

{% extends 'application.html' %}

{% block title %}Login{% endblock %}

{% block content %}
<h2>Login</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Login</button>
</form>
{% endblock %}


次にurls.pyを修正し、/のurlパターンの際に読み込むTemplateを指定してあげます。


urls.py

from django.contrib import admin

from django.urls import include, path
from django.views.generic.base import TemplateView

urlpatterns = [
path('admin/', admin.site.urls),
path('accounts/', include('django.contrib.auth.urls')),
path('', TemplateView.as_view(template_name='index.html'), name='index'),
]


最後にLOGIN_REDIRECT_URLを/からindexに変更します。


settings.py

LOGIN_REDIRECT_URL = 'index'


以上でログイン遷移のページまで作成することができました。

login.gif


あとがき

もうちょいペースアップします。


シリーズ

Part 1Part 2Part 3


参考文献