GoogleAppEngine用フレームワーク「Kay」のデータストア認証で使用するDatastoreUserを継承して属性を追加する方法。
データストア認証で使用するクラスに属性を追加するには、DatastoreUserを継承したクラスを作成します。
総論
ポイントとしては、
- kay.auth.models.DatastoreUserを継承したクラスを作成する。
- settings.AUTH_USER_MODELにkay.auth.models.DatastoreUserを継承したクラスを指定する。
- 登録するときはcreate_new_user()関数を使う。追加した属性はキーワード引数で指定する。
その他は、Kayのドキュメント「1. Kay チュートリアル」「9. 認証の設定」と同じようなものです。
プロジェクトの作成
プロジェクトを作成します。
$ python kay/manage.py startproject myproject
$ cd myproject
$ python manage.py startapp myapp
次のようにファイルが作成されました。
myproject
|-- kay/
|-- myapp/
|-- app.yaml
|-- favicon.ico
|-- manage.py
|-- settings.py
`-- urls.py
settings.pyを編集して、myappを登録します。
settings.py
INSTALLED_APPS = (
'myapp',
)
APP_MOUNT_POINTS = {
'myapp': '/',
}
認証用ミドルウェアを有効にする
settings.MIDDLEWARE_CLASSES に kay.auth.middleware.AuthenticationMiddleware を追加し、認証機構を有効にします。
settings.py
MIDDLEWARE_CLASSES = (
'kay.auth.middleware.AuthenticationMiddleware',
)
ログインボックスを使用するために、settings.INSTALLED_APPS に kay.auth を追加します。
また、settings.CONTEXT_PROCESSORSに kay.auth.context_processors.login_box を追加します。
INSTALLED_APPS = (
'kay.auth',
'myapp',
)
CONTEXT_PROCESSORS = (
…
'kay.auth.context_processors.login_box',
)
データストア認証を有効にする
データストア認証に必要なSessionMiddlewareを有効にするため、settings.MIDDLEWARE_CLASSES に kay.auth.middleware.SessionMiddleware を追加します。
settings.py
MIDDLEWARE_CLASSES = (
'kay.sessions.middleware.SessionMiddleware',
'kay.auth.middleware.AuthenticationMiddleware',
)
settigns.AUTH_USER_BACKEND に kay.auth.backends.datastore.DatastoreBackend を設定します。
DatastoreUserを継承したクラスMyUserを作成し、認証に使用するクラスとして設定します。
settings.py
AUTH_USER_BACKEND = 'kay.auth.backends.datastore.DatastoreBackend'
AUTH_USER_MODEL = 'myapp.MyUser'
認証用クラスを作成する
DatastoreUserを継承したクラスMyUserを作成します。
address属性を追加します。
myapp/models.py
# -*- coding: utf-8 -*-
from google.appengine.ext import db
from kay.auth.models import DatastoreUser
class MyUser(DatastoreUser):
address = db.TextProperty(u'住所', required=True)
ユーザー登録フォームを作成する
ユーザー登録フォームを作成します。
パスワードの入力を確認するために、パスワードを再入力する入力欄を追加します。
myapp/views.py
from kay.utils import forms
from kay.utils.validators import ValidationError
class MyUserForm(forms.Form):
user_name = forms.TextField(u'ユーザー名', required=True)
password = forms.TextField(u'パスワード', required=True)
password_confirm = forms.TextField(u'パスワードの再入力', required=True, widget=forms.PasswordInput)
address = forms.TextField(u'住所', required=True)
def context_validate(self, data):
'''パスワードの再入力チェック'''
if data['password'] != data['password_confirm']:
raise ValidationError(u'パスワードが一致しません。')
ユーザーの入力処理を作成する
認証ユーザーを登録するときはcreate_new_user()関数を使用します。
モデルに追加した属性は、キーワード引数で指定することで、登録することができます。
create_new_user(form['user_name'],
password=form['password'],
address=form['address'])
db.Model.put()を使用して登録すると、ログインボックスからログインすることができません。
ユーザー名がすでに登録されているときはDuplicateKeyErrorが発生します。
try:
create_new_user(…)
msg = u'ユーザーを登録しました。'
except DuplicateKeyError:
msg = u'既に同じユーザー名が登録されています。'
myapp/views.py
from kay.utils import forms
from kay.utils.validators import ValidationError
from kay.auth import (create_new_user, DuplicateKeyError)
import models
def index(request):
form = MyUserForm()
msg = u''
if request.method == 'POST':
if form.validate(request.form):
try:
create_new_user(form['user_name'],
password=form['password'],
address=form['address'])
msg = u'ユーザーを登録しました。'
except DuplicateKeyError:
msg = u'既に同じユーザー名が登録されています。'
return render_to_response('myapp/index.html',
{'form': form.as_widget(),
'msg': msg,
'users': models.MyUser.all()})
myapp/templates/index.html
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Top Page - myapp</title>
</head>
<body>
{% from "auth/macros.html" import render_loginbox with context %}
<div>
{% if request.user.is_anonymous() %}
{{ render_loginbox() }}
{% else %}
Hello {{ request.user }}! <a href="{{ create_logout_url() }}">ログアウト</a>
{% endif %}
</div>
<div>
<p>{{ msg }}</p>
{{ form()|safe }}
</div>
<table>
<tr><th>ユーザー名</th><th>住所</th></tr>
{% for user in users %}
<tr><td>{{user.user_name}}</td><td>{{user.address}}</td></tr>
{% endfor %}
<table>
</body>
</html>
とても参考になります。
AUTH_USER_MODEL = ‘myapp.MyUser’
これは
AUTH_USER_MODEL = ‘myapp.models.MyUser’
ですよね?