Python | Django | class-based viewsにおけるログインの実装方法
公開日:2021/8/25
更新日:2021/9/19
Pythonには,DjangoというWebアプリケーションフレームワークがある.フレームワークのため,Djangoを利用するとWebアプリを通常よりも短時間で開発することが可能になる.
class-based viewsは,viewsを実装する手段の1つであり,関数の代わりにPythonのオブジェクトとしてviewsを定義する.viewsの作成とデータの追加・更新・削除が容易になる.
本記事では,「class-based viewsにおけるログインの実装方法」を以下6つの構成にて記す.
◆実施環境
Python 3.8.8
Django 3.2.3
VS Code 1.59.0
■class-based viewsにおけるログインの実装方法
新たにフォルダを開く.VS Codeの"File"をクリックし,"Open Folder"からフォルダを選ぶ.
今回は"myclassbasedviewslogintest"という名のフォルダを作成したので,選択する.選択後,以下赤枠のようにフォルダが出来上がる.
VS Codeの"View"を開き,"Terminal"をクリックする.VS Codeの下部にターミナルが開くので,”conda activate 仮想環境名”を実行し,仮想環境に移行する(移行方法の詳細はこちら).その後以下のように”django-admin startproject プロジェクト名”を実行する.プロジェクト名は"views_login"にした.
(djangoenv) C:\Users\shiro\Desktop\210517_python development\myclassbasedviewslogintest
>django-admin startproject views_login
ターミナルで"cd views_login"を入力し,ディレクトリを変更する.その後,"python manage.py startapp アプリ名"を入力する.アプリ名は"account"にした.
(djangoenv) C:\Users\shiro\Desktop\210517_python development\myclassbasedviewslogintest\views_login
>python manage.py startapp account
VS Codeにプロジェクト名"views_login"とアプリ名"account"が以下のように作成された.
“views_login/settings.py"のINSTALLED_APPを以下のように編集する.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'account', # 追記箇所
]
“account/models.py"を以下のように編集する.
from django.db import models
from django.contrib.auth.models import (
BaseUserManager, AbstractBaseUser, PermissionsMixin,
)
from django.urls import reverse_lazy
class UserManager(BaseUserManager):
def create_user(self, email, date_of_birth, password=None):
if not email:
raise ValueError('You need Email address!')
user = self.model(
email=email,
date_of_birth=date_of_birth,
)
user.set_password(password)
user.save(using=self._db)
return user
class MyUser(AbstractBaseUser, PermissionsMixin):
username = models.CharField(max_length=100)
email = models.EmailField(max_length=100, unique=True)
date_of_birth = models.DateField()
is_active = models.BooleanField(default=True)
is_staff = models.BooleanField(default=False)
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['date_of_birth']
objects = UserManager()
def get_absolute_url(self):
return reverse_lazy('account:top')
“views_login/settings.py"のINSTALLED_APPの下に追記し,以下のように編集する.
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'account',
]
AUTH_USER_MODEL = 'account.MyUser' # 追記箇所
以下にてマイグレーションを実施する.ターミナルで"cd views_login"を入力し,ディレクトリを変更する.その後,"python manage.py makemigrations account"を入力する.以下が出力される.
(djangoenv) C:\Users\shiro\Desktop\210517_python development\myclassbasedviewslogintest\views_login
>python manage.py makemigrations account
Migrations for 'account': # 以下出力箇所
account\migrations\0001_initial.py
- Create model MyUser
続けて,ターミナルで"python manage.py migrate"を入力する.以下が出力されれば,成功となる.
(djangoenv) C:\Users\shiro\Desktop\210517_python development\myclassbasedviewslogintest\views_login
>python manage.py migrate
Operations to perform: # 以下出力箇所
Apply all migrations: account, admin, auth, contenttypes, sessions
Running migrations:
Applying contenttypes.0001_initial... OK
Applying contenttypes.0002_remove_content_type_name... OK
Applying auth.0001_initial... 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 auth.0010_alter_group_name_max_length... OK
Applying auth.0011_update_proxy_permissions... OK
Applying auth.0012_alter_user_first_name_max_length... OK
Applying account.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 sessions.0001_initial... OK
“account/views.py"を以下のように編集する.
from django.shortcuts import render
from django.views.generic.edit import CreateView
from django.views.generic.base import TemplateView
class TopView(TemplateView):
template_name = 'top.html'
class RegistrationView(CreateView):
template_name = 'registration.html'
“account"に"forms.py"を以下のように作成する.
“account/forms.py"を以下のように編集する.
from django import forms
from .models import MyUser
from django.contrib.auth.password_validation import validate_password
class RegistrationForm(forms.ModelForm):
username = forms.CharField(label='name')
date_of_birth = forms.DateField(label='date_of_birth')
email = forms.EmailField(label='email address')
password = forms.CharField(label='password', widget=forms.PasswordInput())
class Meta:
model = MyUser
fields = ['username', 'date_of_birth', 'email', 'password']
def save(self, commit=False):
user = super().save(commit=False)
validate_password(self.cleaned_data['password'], user)
user.set_password(self.cleaned_data['password'])
user.save()
return user
“account/views.py"に追記し,以下のように編集する.
from django.shortcuts import render
from django.views.generic.edit import CreateView, FormView # 変更箇所(2~4行目)
from django.views.generic.base import TemplateView, View
from .forms import RegistrationForm
class TopView(TemplateView):
template_name = 'top.html'
class RegistrationView(CreateView):
template_name = 'registration.html'
form_class = RegistrationForm # 以下追記箇所
class MyLoginView(FormView):
pass
class MyLogoutView(View):
pass
“account"フォルダに"urls.py"を以下のように作成する.
“account/urls.py"を以下のように編集する.
from django.urls import path
from .views import (
TopView, RegistrationView,
MyLoginView, MyLogoutView
)
app_name = 'account'
urlpatterns = [
path('top/', TopView.as_view(), name='top'),
path('registration/', RegistrationView.as_view(), name='registration'),
path('login/', MyLoginView.as_view(), name='login'),
path('logout/', MyLogoutView.as_view(), name='logout'),
]
“views_login/urls.py"に追記し,以下のように編集する.
from django.contrib import admin
from django.urls import path, include # 変更箇所
urlpatterns = [
path('admin/', admin.site.urls),
path('account/', include('account.urls')), # 追記箇所
]
“views_login/settings.py"に追記し,以下のように編集する.
from pathlib import Path
import os # 追記箇所
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
TEMPLATE_DIR = os.path.join(BASE_DIR, 'templates') # 追記箇所
~省略~
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [TEMPLATE_DIR,], # 変更箇所
'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',
],
},
},
]
“views_login"プロジェクトフォルダに"templates"フォルダを作成し,その中に"base.html"を作成する.
以下URLにアクセスし,linkをコピーする.
https://getbootstrap.com/docs/5.0/getting-started/introduction/#css
“templates/base.html"を以下のように編集する.5行目にコピーしたlinkを貼り付けする.
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
</head>
<body>
<nav class="navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="{% url 'account:top' %}"> Top</a>
{% if user.is_authenticated %}
<a class="navbar-brand" href="{% url 'account:logout' %}">Logout</a>
{% else %}
<a class="navbar-brand" href="{% url 'account:login' %}">Login</a>
<a class="navbar-brand" href="{% url 'account:registration' %}">Registration</a>
{% endif %}
</nav>
{% block content %}{% endblock %}
</body>
</html>
“templates"フォルダに"top.html"と"registration.html"を以下のように作成する.
“top.html"を以下のように編集する.
{% extends 'base.html' %}
{% block content %}
<h2><p> Hello World!</p></h2>
<h2><p> This is Top Page!</p></h2>
{% endblock %}
“registration.html"を以下のように編集する.
{% extends 'base.html' %}
{% block content %}
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Registration">
</form>
{% endblock %}
VS Codeのターミナルで,”conda activate 仮想環境名”を実行し,ターミナルで"cd views_login"(プロジェクト名)を入力し,ディレクトリを変更する.変更後,以下のように”python manage.py runserver”を実行する.以下が出力される.
(djangoenv) C:\Users\shiro\Desktop\210517_python development\myclassbasedviewtest\class_based_view
>python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced). # 以下出力箇所
August 24, 2021 - 15:49:19
Django version 3.2.3, using settings 'class_based_view.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
上記の"http://127.0.0.1:8000/"をクリックすると,ブラウザが開き,以下画面が出力される.
ブラウザのURLに"http://127.0.0.1:8000/account/top"と入力すると,以下トップページに遷移する."Registration"をクリックする.
以下画面に遷移する.
以下ページで以下のように記述し,"Registration"ボタンをクリックする.
問題がなければ,以下トップページに遷移する.
VS Codeにおいて,SQLiteをインストールし(詳細はこちら参照),"SQLITE EXPLORER"を開くと,"account_myuser"テーブルを以下のように確認できる.
“account_myuser"テーブルを右クリックし,"Show Table"をクリックすると以下のように上記で記述したユーザー内容を確認することができる.
“account/forms.py"に追記し,以下のように編集する.
from django import forms
from .models import MyUser
from django.contrib.auth.password_validation import validate_password
class RegistrationForm(forms.ModelForm):
username = forms.CharField(label='name')
date_of_birth = forms.DateField(label='date_of_birth')
email = forms.EmailField(label='email address')
password = forms.CharField(label='password', widget=forms.PasswordInput())
class Meta:
model = MyUser
fields = ['username', 'date_of_birth', 'email', 'password']
def save(self, commit=False):
user = super().save(commit=False)
validate_password(self.cleaned_data['password'], user)
user.set_password(self.cleaned_data['password'])
user.save()
return user
class LoginForm(forms.Form): # 以下追記箇所
email = forms.EmailField(label='email address')
password = forms.CharField(label='password', widget=forms.PasswordInput())
“account/views.py"に追記し,以下のように編集する.
from django.shortcuts import render, redirect # 変更箇所
from django.views.generic.edit import CreateView, FormView
from django.views.generic.base import TemplateView, View
from .forms import RegistrationForm, LoginForm # 変更箇所
from django.contrib.auth import authenticate, login, logout # 追記箇所
class TopView(TemplateView):
template_name = 'top.html'
class RegistrationView(CreateView):
template_name = 'registration.html'
form_class = RegistrationForm
class MyLoginView(FormView):
template_name = 'login.html' # 以下追記箇所
form_class = LoginForm
def post(self, request, *args, **kwargs):
email = request.POST['email']
password = request.POST['password']
user = authenticate(email=email, password=password)
if user is not None and user.is_active:
login(request, user)
return redirect('account:top')
class MyLogoutView(View):
def get(self, request, *args, **kwargs):
logout(request)
return redirect('account:login')
“account/views.py"に"login.html"を記述したので,"templates"フォルダに"login.html"を以下のように作成する.
“templates/login.html"を以下のように編集する.
{% extends 'base.html' %}
{% block content %}
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="submit" value="Login">
</form>
{% endblock %}
上記を保存し,ブラウザのURLに"http://127.0.0.1:8000/account/top"と入力すると,以下トップページに遷移する."Login"をクリックする.
以下ログインページに遷移する.
上記の項目2で登録したメールアドレスとパスワードを入力し,"Login"ボタンをクリックする.
以下画面に遷移し,上部は"Top"と"Logout"のみ表記される."Logout"をクリックする.
以下のようにログインページに遷移する.
“account/views.py"に追記し,以下のように編集する.
from django.shortcuts import render, redirect
from django.views.generic.edit import CreateView, FormView
from django.views.generic.base import TemplateView, View
from .forms import RegistrationForm, LoginForm
from django.contrib.auth import authenticate, login, logout
class TopView(TemplateView):
template_name = 'top.html'
class RegistrationView(CreateView):
template_name = 'registration.html'
form_class = RegistrationForm
class MyLoginView(FormView):
template_name = 'login.html'
form_class = LoginForm
def post(self, request, *args, **kwargs):
email = request.POST['email']
password = request.POST['password']
user = authenticate(email=email, password=password)
if user is not None and user.is_active:
login(request, user)
return redirect('account:top')
class MyLogoutView(View):
def get(self, request, *args, **kwargs):
logout(request)
return redirect('account:login')
class MyUserView(TemplateView): # 以下追記箇所
template_name = 'user.html'
“account/views.py"で"user.html"を記載したので,"templates"フォルダに"user.html"を以下のように作成する.
“templates/user.html"を以下のように編集する.
{% extends 'base.html' %}
{% block content %}
<h2><p> Hello World!</p></h2>
<h2><p> This is User Page!</p></h2>
{% endblock %}
“account/urls.py"に追記し,以下のように編集する.
from django.urls import path
from .views import ( # 変更箇所
TopView, RegistrationView,
MyLoginView, MyLogoutView,
MyUserView,
)
app_name = 'account'
urlpatterns = [
path('top/', TopView.as_view(), name='top'),
path('registration/', RegistrationView.as_view(), name='registration'),
path('login/', MyLoginView.as_view(), name='login'),
path('logout/', MyLogoutView.as_view(), name='logout'),
path('user/', MyUserView.as_view(), name='user'), # 追記箇所
]
“templates/base.html"に追記し,以下のように編集する.
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous">
</head>
<body>
<nav class="navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="{% url 'account:top' %}"> Top</a>
{% if user.is_authenticated %}
<a class="navbar-brand" href="{% url 'account:logout' %}">Logout</a>
{% else %}
<a class="navbar-brand" href="{% url 'account:login' %}">Login</a>
<a class="navbar-brand" href="{% url 'account:registration' %}">Registration</a>
{% endif %}
<a class="navbar-brand" href="{% url 'account:user' %}">User Page</a> # 追記箇所
</nav>
{% block content %}{% endblock %}
</body>
</html>
VS Codeのターミナルで,”conda activate 仮想環境名”を実行し,"views_login"のディレクトリにて,以下のように”python manage.py runserver”を実行する.以下が出力される.
(djangoenv) C:\Users\shiro\Desktop\210517_python development\myclassbasedviewtest\class_based_view
>python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced). # 以下出力箇所
August 25, 2021 - 13:41:40
Django version 3.2.3, using settings 'class_based_view.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
上記の"http://127.0.0.1:8000/"をクリックすると,ブラウザが開くので,ブラウザのURLに"http://127.0.0.1:8000/account/top"を入力すると以下のようにトップページに遷移する.トップページに"Use Page"が赤枠のように追記された.
上記の"Use Page"をクリックすると,以下のように"User Page"に遷移した.
“account/views.py"に追記し,以下のように編集する.
from django.shortcuts import render, redirect
from django.views.generic.edit import CreateView, FormView
from django.views.generic.base import TemplateView, View
from .forms import RegistrationForm, LoginForm
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required # 追記箇所(6~8行目)
from django.utils.decorators import method_decorator
from django.contrib.auth.mixins import LoginRequiredMixin
class TopView(TemplateView):
template_name = 'top.html'
class RegistrationView(CreateView):
template_name = 'registration.html'
form_class = RegistrationForm
class MyLoginView(FormView):
template_name = 'login.html'
form_class = LoginForm
def post(self, request, *args, **kwargs):
email = request.POST['email']
password = request.POST['password']
user = authenticate(email=email, password=password)
if user is not None and user.is_active:
login(request, user)
return redirect('account:top')
class MyLogoutView(View):
def get(self, request, *args, **kwargs):
logout(request)
return redirect('account:login')
class MyUserView(TemplateView):
template_name = 'user.html'
@method_decorator(login_required) # 以下追記箇所
def dispatch(self, *args, **kwargs):
return super().dispatch(*args, **kwargs)
“views_login/settings.py"の最下部に追記し,以下のように編集する.
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
LOGIN_URL = '/account/login' # 追記箇所
上記を保存し,ブラウザから"http://127.0.0.1:8000/account/top"に以下のように遷移する.
上記の"User Page"をクリックすると,以下のようにログインページに遷移した."User Page"は,ログインをしていなければ遷移させることができないようにした.そのため,リダイレクトでログインページに遷移した.
“User Page"でリダイレクトし,ログインページに遷移する場合と直接ログインページに遷移する場合,URLには以下のような差がある.
直接ログインページに遷移:http://127.0.0.1:8000/account/login/
“User Page"からログインページに遷移:http://127.0.0.1:8000/account/login/?next=/account/user/
この差を利用し,"User Page"でリダイレクトし,ログインページに遷移する場合,ログイン後に"User Page"に遷移するようにコードを記述していく.
“account/views.py"に追記し,以下のように編集する.
from django.shortcuts import render, redirect
from django.views.generic.edit import CreateView, FormView
from django.views.generic.base import TemplateView, View
from .forms import RegistrationForm, LoginForm
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.contrib.auth.mixins import LoginRequiredMixin
class TopView(TemplateView):
template_name = 'top.html'
class RegistrationView(CreateView):
template_name = 'registration.html'
form_class = RegistrationForm
class MyLoginView(FormView):
template_name = 'login.html'
form_class = LoginForm
def post(self, request, *args, **kwargs):
email = request.POST['email']
password = request.POST['password']
user = authenticate(email=email, password=password)
next_url = request.POST['next'] # 追記箇所
if user is not None and user.is_active:
login(request, user)
if next_url: # 追記箇所(28~29行目)
return redirect(next_url)
return redirect('account:top')
class MyLogoutView(View):
def get(self, request, *args, **kwargs):
logout(request)
return redirect('account:login')
class MyUserView(TemplateView):
template_name = 'user.html'
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super().dispatch(*args, **kwargs)
“templates/login.html"に追記し,以下のように編集する.
{% extends 'base.html' %}
{% block content %}
<form method="POST">
{% csrf_token %}
{{ form.as_p }}
<input type="hidden" name="next" value="{{ request.GET.next }}"> # 追記箇所
<input type="submit" value="Login">
</form>
{% endblock %}
上記を保存し,ブラウザから"http://127.0.0.1:8000/account/top"に以下のように遷移する.
上記の"User Page"をクリックすると,以下のようにログインページに遷移した.
以下のように上記で登録したユーザー情報を用いてログインを行う.
ログイン後,以下のように"User Page"に遷移した.
なお,Top Pageから"Login"をクリックし,以下のようにログインする.
ログイン後,以下のように"Top Page"に遷移した.
項目3にてログイン・ログアウトの実装をしたが,項目4では異なるコードでログイン・ログアウトの実装を行う.
“account/views.py"を以下のように編集する.
from django.shortcuts import render, redirect
from django.views.generic.edit import CreateView, FormView
from django.views.generic.base import TemplateView, View
from .forms import RegistrationForm, LoginForm
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.views import LoginView, LogoutView # 追記箇所
class TopView(TemplateView):
template_name = 'top.html'
class RegistrationView(CreateView):
template_name = 'registration.html'
form_class = RegistrationForm
class MyLoginView(LoginView): # 追記箇所(18~20行目)
template_name = 'login.html'
authentication_form = LoginForm
class MyLogoutView(View):
def get(self, request, *args, **kwargs):
logout(request)
return redirect('account:login')
class MyUserView(TemplateView):
template_name = 'user.html'
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super().dispatch(*args, **kwargs)
“account/forms.py"を以下のように編集する.
from django import forms
from .models import MyUser
from django.contrib.auth.password_validation import validate_password
from django.contrib.auth.forms import AuthenticationForm # 追記箇所
class RegistrationForm(forms.ModelForm):
username = forms.CharField(label='name')
date_of_birth = forms.DateField(label='date_of_birth')
email = forms.EmailField(label='email address')
password = forms.CharField(label='password', widget=forms.PasswordInput())
class Meta:
model = MyUser
fields = ['username', 'date_of_birth', 'email', 'password']
def save(self, commit=False):
user = super().save(commit=False)
validate_password(self.cleaned_data['password'], user)
user.set_password(self.cleaned_data['password'])
user.save()
return user
class LoginForm(AuthenticationForm): # 以下追記箇所
username = forms.EmailField(label='Email Address')
password = forms.CharField(label='Password', widget=forms.PasswordInput())
“views_login/settings.py"に追記し,以下のように編集する.
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
LOGIN_URL = '/account/login'
LOGIN_REDIRECT_URL = '/account/top' # 追記箇所
VS Codeのターミナルで,”conda activate 仮想環境名”を実行し,"views_login"のディレクトリにて,以下のように”python manage.py runserver”を実行する.以下が出力される.
(djangoenv) C:\Users\shiro\Desktop\210517_python development\myclassbasedviewtest\class_based_view
>python manage.py runserver
Watching for file changes with StatReloader
Performing system checks...
System check identified no issues (0 silenced). # 以下出力箇所
August 25, 2021 - 16:03:19
Django version 3.2.3, using settings 'class_based_view.settings'
Starting development server at http://127.0.0.1:8000/
Quit the server with CTRL-BREAK.
上記の"http://127.0.0.1:8000/"をクリックすると,ブラウザが開くので,ブラウザのURLに"http://127.0.0.1:8000/account/top"を入力すると以下のようにトップページに遷移する.
ログイン画面に移動し,以下のように登録した情報を記入し,"Login"ボタンをクリックする.
以下のようにログインに成功し,"Top Page"に遷移した.
“account/views.py"を以下のように編集する.
from django.shortcuts import render, redirect
from django.views.generic.edit import CreateView, FormView
from django.views.generic.base import TemplateView, View
from .forms import RegistrationForm, LoginForm
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.views import LoginView, LogoutView
class TopView(TemplateView):
template_name = 'top.html'
class RegistrationView(CreateView):
template_name = 'registration.html'
form_class = RegistrationForm
class MyLoginView(LoginView):
template_name = 'login.html'
authentication_form = LoginForm
class MyLogoutView(LogoutView): # 追記箇所
pass # 追記箇所
class MyUserView(TemplateView):
template_name = 'user.html'
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super().dispatch(*args, **kwargs)
“views_login/settings.py"に追記し,以下のように編集する.
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
LOGIN_URL = '/account/login'
LOGIN_REDIRECT_URL = '/account/top'
LOGOUT_REDIRECT_URL = '/account/login' # 追記箇所
上記の"http://127.0.0.1:8000/"をクリックすると,ブラウザが開くので,ブラウザのURLに"http://127.0.0.1:8000/account/top"を入力すると以下のようにトップページに遷移する."Login"をクリックする.
以下画面に遷移するので,登録情報を記入し,"Login"ボタンをクリックする.
ログインに成功し,以下のようにTop Pageに遷移する."Logout"をクリックする.
ログイン後,以下のようにログインページに遷移する.
“views_login/settings.py"に追記し,以下のように編集する.ログインの保持を10秒にすることを意味している.
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
LOGIN_URL = '/account/login'
LOGIN_REDIRECT_URL = '/account/top'
LOGOUT_REDIRECT_URL = '/account/login'
SESSION_COOKIE_AGE = 10 # 追記箇所
上記を保存し,ブラウザから"http://127.0.0.1:8000/account/top"に以下のように遷移する.
ログインをすることによって,"Top Page"に遷移する.
10秒後に更新すると,以下のように自動的にログアウト状態になる.
“account/forms.py"に追記し,以下のように編集する.
from django import forms
from .models import MyUser
from django.contrib.auth.password_validation import validate_password
from django.contrib.auth.forms import AuthenticationForm
class RegistrationForm(forms.ModelForm):
username = forms.CharField(label='name')
date_of_birth = forms.DateField(label='date_of_birth')
email = forms.EmailField(label='email address')
password = forms.CharField(label='password', widget=forms.PasswordInput())
class Meta:
model = MyUser
fields = ['username', 'date_of_birth', 'email', 'password']
def save(self, commit=False):
user = super().save(commit=False)
validate_password(self.cleaned_data['password'], user)
user.set_password(self.cleaned_data['password'])
user.save()
return user
class LoginForm(AuthenticationForm):
username = forms.EmailField(label='Email Address')
password = forms.CharField(label='Password', widget=forms.PasswordInput())
remember = forms.BooleanField(label='keep login', required=False) # 以下追記箇所
“account/views.py"に追記し,以下のように編集する.
from django.shortcuts import render, redirect
from django.views.generic.edit import CreateView, FormView
from django.views.generic.base import TemplateView, View
from .forms import RegistrationForm, LoginForm
from django.contrib.auth import authenticate, login, logout
from django.contrib.auth.decorators import login_required
from django.utils.decorators import method_decorator
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.views import LoginView, LogoutView
class TopView(TemplateView):
template_name = 'top.html'
class RegistrationView(CreateView):
template_name = 'registration.html'
form_class = RegistrationForm
class MyLoginView(LoginView):
template_name = 'login.html'
authentication_form = LoginForm
def form_valid(self, form): # 追記箇所(以下5行が追記箇所)
remember = form.cleaned_data['remember']
if remember:
self.request.session.set_expiry(1000000)
return super().form_valid(form)
class MyLogoutView(LogoutView):
pass
class MyUserView(TemplateView):
template_name = 'user.html'
@method_decorator(login_required)
def dispatch(self, *args, **kwargs):
return super().dispatch(*args, **kwargs)
上記を保存し,ブラウザから"http://127.0.0.1:8000/account/top"に以下のように遷移する."Login"をクリックする.
以下のようにログインページに遷移する.赤枠の"keep login"が加わった.チェックをするとログイン状態をキープすることができる.チェックをしないと10秒でログアウト状態になる.
以下のようにユーザー情報を記述し,"keep login"にチェックを入れ,"Login"ボタンをクリックする.
以下のようにログイン状態になり,Top Pageに遷移した.
10秒後,更新をしてもログアウトにならない.
本記事にてアプリ名を"account"と名付けたが,「OAuth認証を用いたgoogleでのログイン方法」で当該アプリ名はエラーを引き起こした.そのため,当該アプリ名は付与せず,"myaccount"などを利用するほうがよい.
https://docs.djangoproject.com/en/3.2/topics/auth/customizing/#custom-users-and-proxy-models
https://docs.djangoproject.com/ja/3.1/topics/class-based-views/intro/#decorating-the-class
https://docs.djangoproject.com/en/3.2/topics/auth/default/#the-login-required-decorator
https://docs.djangoproject.com/en/3.2/topics/class-based-views/intro/#decorating-the-class
https://docs.djangoproject.com/en/3.1/topics/auth/default/
https://docs.djangoproject.com/en/3.1/topics/http/sessions/
https://docs.djangoproject.com/en/3.1/ref/settings/#session-cookie-age
https://docs.djangoproject.com/ja/3.1/topics/http/sessions/#django.contrib.sessions.backends.base.SessionBase.set_expiry
以上