ログイン認証してみる

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
ツールボックス

下から選んでください:

新しいページを作成する
ヘルプ / FAQ もご覧ください。