Djangoには予めログイン認証用のモジュールが用意されている。
よく出来てるのでスクラッチで書く必要はほとんど無い。
最近のバージョンでは、必須フィールドのusernameに「@」や「.」が使えるようになってるので
メールアドレスをログインIDにすることも出来る
(バリデーターに細工は必要っぽいけど)
よく使うインポート
from django.contrib import auth
from django.contrib.auth.models import User
よく使うビュー
'django.contrib.auth.views.login'
'django.contrib.auth.views.logout_then_login'
'django.contrib.auth.views.change_password'
settings
INSTALLED_APP = (
#...
'django.contrib.auth',
'django.contrib.contenttypes',
#...
LOGIN_URL = "/account/login/"
LOGIN_REDIRECT_URL = "/account/mypage/"
INSTALLED_APPはほとんどの場合、最初から追加されているはず。
テンプレート
ログイン認証に必要な画面は自分で作る必要がある。
とは言っても、予めフォームが用意されてるのでほとんど手間は要らない。
ログイン画面: login.html
{% extends "base.html" %}
{% load url from future %}
{% block contents %}
{% if form.errors %}
<p>Eメールアドレスまたはパスワードが違います。</p>
{% endif %}
<form method="post" action="{% url 'django.contrib.auth.views.login' %}">
{% csrf_token %}
<table>
<tr><td>{{ form.username.label_tag }}</td><td>{{ form.username }}</td></tr>
<tr><td>{{ form.password.label_tag }}</td><td>{{ form.password }}</td></tr>
</table>
<input type="submit" value="login" />
<input type="hidden" name="next" value="{{ next }}" />
</form>
{% endblock %}
もっと簡単に {{form}}でもOK。その場合はエラーの表示がフィールドごと個別に出るはず。どんな内容か確認はしてないが。
urls
urlpatterns = patterns('',
(r'^account/login/$', 'django.contrib.auth.views.login', {'template_name':'account/login.html'}),
(r'^account/logout/$', 'django.contrib.auth.views.logout_then_login'),
# ...
UserManager
from django.contrib.auth.models import UserManager
UserManager.create_user(username, email=None, password=None)
UserProfile
ユーザーに追加情報を紐付けられる。
settings.py
AUTH_PROFILE_MODULE = 'accounts.Member'
DOCSによると modelsは要らないらしい。試してないからどうだか。
あとはmodelsにModelの定義と、user作成時にsignalでインスタンスが作られるように細工する。
signalへの登録は必須ではなく、コードを書くならそれでもいい。本家のドキュメントに載ってたので一応書いておいただけ。
models.py
from django.contrib.admin.models import User
class Member(models.Model):
user = models.OneToOneField(User)
personal_project = models.OneToOneField(Project)
def __unicode__(self):
return 'profile of %s' % self.user
from django.db.models.signals import post_save
def create_user_profile(sender, instance, created, **kwargs):
if created:
Member.objects.create(user=instance)
post_save.connect(create_user_profile, sender=User)
予め用意された画面
パスワード変更と、パスワードリセットは予め画面が用意されている。
urlsにこんな感じで追加しておく。
url(r'^account/changepw/$', 'django.contrib.auth.views.password_change'),
url(r'^account/changepw/done/$', 'django.contrib.auth.views.password_change_done'),
url(r'^account/resetpw/$', 'django.contrib.auth.views.password_reset'),
url(r'^account/resetpw/done/$', 'django.contrib.auth.views.password_reset_done'),
url(r'^account/resetpw/confirm/(?P<uidb36>.+)/(?P<token>.+)/$', 'django.contrib.auth.views.password_reset_confirm'),
url(r'^account/resetpw/complete/$', 'django.contrib.auth.views.password_reset_complete'),
変更は確認したけど、リセットは確認してない。
開発マシンにメール送信サーバーが無くポートをリッスンしてないのでエラー(10061)が発生するみたい。
ユーザーの登録、情報変更はAdminから行うことになる。
ユーザーサイドでできるようにするなら画面を作ることになる。
(フォームとユーティリティークラス、メソッドは用意されてる)
制限
@login_required
def honyahonya(request)
ログインしてない場合、ログイン画面に遷移し、さらにログインフォームでnext にセットされたURLにリダイレクトする。nextへのセットは自動でやってくれる(GETで?next=/honyahonya/1/みたいな具合)が、reverseで解決できる必要がある(と思う)
ユーザー登録
簡単な登録フォームを作る。メールによる確認。CAPTCHAなどのスパム対策はしてない。
views.py
def register(request):
if request.method == 'GET':
return render(request, 'account/register.html', {'form':UserCreationForm()})
elif request.method == 'POST':
form = UserCreationForm(request.POST)
if form.is_valid():
form.save()
return render_to_response('account/register_done.html', {'username':form['username'].value()})
else:
return render(request, 'account/register.html', {'form':form})
else:
return HttpResponseForbidden
render と render_to_response の違いは、renderは必ずrequestをパラメータに取り、レスポンスのcontextに含める点。フォームを表示する場合はcsrf_tokenなどの関係から renderを使うのが良い。
register.html
{% extends 'index.html' %}
{% load url from future %}
{% block contents %}
<form method="post" action="{% url 'projects.views.account.register' %}">
{% csrf_token %}
{{form.as_p}}
<input type="submit" value="アカウント作成" />
</form>
{% endblock %}
reister_done.html
{% extends 'index.html' %}
{% load url from future %}
{% block contents %}
<h3>{{username}}を登録しました。</h3>
画面上部のリンクからログインしてください。
{% endblock %}
urls.py patternsに追加
url(r'^account/register/$', account.register),
最終更新:2012年11月14日 12:19