前回まででログイン・ログアウトの機能は追加されました。管理画面からユーザーは追加できますが、ユーザー自身が入力して登録できるようにしましょう。
djangoではユーザー登録のビューは用意されていませんが、フォームは予め用意されているので、それを使います。
account内にforms.pyを作成し、下記の通り保存します。
from .models import User
from django.contrib.auth.forms import UserCreationForm
class SignUpForm(UserCreationForm):
class Meta:
model = User
fields = ('username', 'email', 'password1', 'password2')
djangoで用意されているUserCreationFormは通常のモデルフォームに加えてパスワードの欄が二つ(password1とpassword2)を追加されていて、それらが一致しているか検証する機能を追加したものです。
ここではusernameとemailとpassword1、password2をフィールドとして指定していますが、これ以外のuserモデルのフィールドを指定しても問題ありません。
password1とpassword2に入力された値は問題なく一致しているか検証されて、問題なければuserのpasswordとしてセットされます。
次にaccountのviews.pyを編集していきます。
from django.shortcuts import render
from django.contrib.auth.views import LoginView, LogoutView
from django.http import HttpResponseRedirect
#以下追加
from django.urls import reverse_lazy
from django.views.generic.edit import CreateView
from .forms import SignUpForm
class Login(LoginView):
template_name="account/login.html"
class Logout(LogoutView):
template_name="account/logout.html"
#以下追加
class SignUp(CreateView):
form_class = SignUpForm
template_name = "account/signup.html"
success_url = reverse_lazy('account:login')
ここではCreateViewを使っています。中身は特に説明不要かなと思いますが、先程作成したフォームの指定と、テンプレートの指定、登録完了時のジャンプ先を指定しています。
from django.urls import path
from .views import Login,Logout,SignUp
app_name='account'
urlpatterns = [
path('login/', Login.as_view(),name='login'),
path('logout/', Logout.as_view(),name='logout'),
path('signup/', SignUp.as_view(),name='signup'),#追加
]
ここではurls.pyを編集しています。単純に先程作成したsignupのビューをインポートしてパスに追加しているだけですね。
{% extends 'base/base.html' %}
{% load crispy_forms_tags %}
{%block content%}
<div class="card mx-auto" style="margin-top:150px; width: 100%;max-width: 330px;">
<div class="card-body">
<h4 class="card-title">新規ユーザー登録</h4>
{{ form.media }}
<form action="" method="POST">
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-primary">登録</button>
</form>
</div>
</div>
{%endblock%}
テンプレートの例です。ほとんどログインフォームの使いまわしです。
{% extends 'base/base.html' %}
{% load crispy_forms_tags %}
{%block content%}
<div class="card mx-auto" style="margin-top:150px; width: 100%;max-width: 330px;">
<div class="card-body">
<h4 class="card-title">ログイン</h4>
{{ form.media }}
<form action="" method="POST">
{% csrf_token %}
{{ form|crispy }}
<button type="submit" class="btn btn-primary mr-3">ログイン</button><a href="{%url 'account:signup'%}" class="btn btn-secondary">新規登録</a>
</form>
</div>
</div>
{%endblock%}
ログインフォームの方には新規登録へのリンクを追加しました。
これでログインが必要なページではログインか新規登録か選べて、ユーザー新規登録出来るようになりましたね。