概要
ログインやログアウトは、Django側で適当なviewを用意してくれているため、実装するのはそれほど大変ではありません。
しかし、ユーザー登録に関しては、サービスやプロダクトによって必要な情報が異なるため、UserCreationFormを使用して少し実装する必要があります。
公式のドキュメントにはそれほど記載がなく、検索をしても書き方が色々あって混乱するため、手元でうまくいった例を残します。
追記: コメントを反映しました。ご指摘ありがとうございます。
環境情報
python: 3.6.5
django:2.0.6
OS: macOS
実装
まず、ユーザー登録の際に使うフォームをカスタマイズしないケース。
具体的には、フォームにUserCreationFormをそのまま使う場合のことをさします。
追記:2019/05/04に編集しました。
from django.contrib.auth import login
from django.http import HttpResponseRedirect
from django.urls import reverse_lazy
from django.views.generic.edit import CreateView
from .forms import SignupForm
class SignUp(CreateView):
form_class = SignupForm
template_name = "accounts/signup.html"
success_url = reverse_lazy('top')
def form_valid(self, form):
user = form.save() # formの情報を保存
login(self.request, user) # 認証
self.object = user
return HttpResponseRedirect(self.get_success_url()) # リダイレクト
公式によると、form_validを編集する方が良いようです。
必須フィールドを増やしたい場合は、UserCreationFormを継承して、少しだけ加工をすると良いです。
例えば、ユーザー名、名前、パスワードを取得したいケースだと
from django.contrib.auth.models import User
from django.contrib.auth.forms import UserCreationForm
class SignUpForm(UserCreationForm):
class Meta:
model = user
fields = ('username', 'email', 'password1', 'password2')
こんな感じで書いて、上のform_classをSignUpFormに変えれば完了です。
あとは、urlsを修正しておきましょう。
from django.urls import path
urlpatterns = [
path('accounts/signup/', SignUp.as_view(), name='signup')
]
おまけ
実際には、バックエンド側の処理を書いたら、フロント側でも反映していくわけですが、サインナップ時のエラーを表示させる方法も残しておきます。
下記の記載は、公式のドキュメントによせて書いてみます。
<!DOCTYPE html>
<html lang="ja">
<head>
{% include 'head.html' %}
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
{% extends 'base.html' %}
{% block content %}
<main>
...
...
{# signup処理部分 #}
<form method="post" action="{% url 'signup' %}">
{% csrf_token %}
<table>
<tr>
<td>{{ form.username.label_tag }}</td>
<td>{{ form.username }}</td>
</tr>
<tr>
<td>{{ form.email.label_tag }}</td>
<td>{{ form.email }}</td>
</tr>
<tr>
<td>{{ form.password1.label_tag }}</td>
<td>{{ form.password1 }}</td>
</tr>
<tr>
<td>{{ form.password2.label_tag }}</td>
<td>{{ form.password2 }}</td>
</tr>
</table>
<input type="submit" value="login" />
{# エラーメッセージを表示 #}
{% if form.errors %}
{% for field in form %}
{% for error in field.errors %}
<p>{{ error }}</p>
{% endfor %}
{% endfor %}
{% endif %}
</form>
{% endblock %}
おわりに
djangoは、認証に関して色々なツールを用意してくれていて、初心者には結構ありがたい。
実用する際には、OAuthなどの対応が必要になるので、その辺りについても調べていきたいです。