Django 1.5のカスタムユーザーモデルとdjango-registration その2
django 1.5でプロジェクト作って、カスタムユーザーモデルを定義してみる。
apps.models.py
from django.contrib.auth.models import AbstractBaseUser from django.db import models from django.utils.translation import ugettext_lazy as _ class MyUser(AbstractBaseUser): email = models.EmailField(_('e-mail address'), unique=True, db_index=True) first_name = models.CharField(_('first name'), max_length=30, blank=True) last_name = models.CharField(_('last name'), max_length=30, blank=True) USERNAME_FIELD = 'email' REQUIRED_FIELDS = []
emailをログインに使うようにしてみる
settings.pyにAUTH_USER_MODELを定義
AUTH_USER_MODEL = 'apps.MyUser'
django-registraionのfork版をINSTALLED_APPSに追加
settings.py
INSTALLED_APPS += ('registration',)
何も考えずにurls.pyにaccounts周りのurlを追加
urlpatterns += patterns('', url(r'^accounts/', include('registration.backends.default.urls')), )
再びsettings.pyにユーザー登録で使用されるメール周りの設定を追加。
手っ取り早くgmailで送信
ACCOUNT_ACTIVATION_DAYS = 7 EMAIL_USE_TLS = True EMAIL_HOST = 'smtp.gmail.com' EMAIL_HOST_USER = 'xxxxxxxxxxxx@gmail.com' # 使用するgmailアカウント EMAIL_HOST_PASSWORD = 'xxxxxxxxxxx' # 使用するgmailアカウントのパスワード EMAIL_PORT = 587 LOGIN_REDIRECT_URL = '/'
テンプレート忘れてた。
そのまま使えるかわからないけど、パッケージで用意されているものを入れてみる
pip install django-registration-defaults
settings.py
INSTALLED_APPS += ('registration', 'registration_defaults')
syncdbしてみる。
superuser作るところでエラー。
AttributeError: 'Manager' object has no attribute 'get_by_natural_key'
Creating tables ... Creating table auth_permission Creating table auth_group_permissions Creating table auth_group Creating table django_content_type Creating table django_session Creating table django_site Creating table django_admin_log Creating table apps_myuser Creating table registration_registrationprofile You just installed Django's auth system, which means you don't have any superusers defined. Would you like to create one now? (yes/no): yes E-mail address: xxxxxxxxxxxxxx@gmail.com AttributeError: 'Manager' object has no attribute 'get_by_natural_key'
カスタムユーザーモデルを使う場合は、Managerも定義しないといけないようだ。
You should also define a custom manager for your User model. If your User model defines username and email fields the same as Django’s default User, you can just install Django’s UserManager; however, if your User model defines different fields, you will need to define a custom manager that extends BaseUserManager providing two additional methods:
Customizing authentication in Django | Django documentation | Django
apps.models.py
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager from django.db import models from django.utils.translation import ugettext_lazy as _ class MyUserManager(BaseUserManager): def create_user(self, email, password=None): if not email: raise ValueError('Users must have an email address') user = self.model(email=BaseUserManager.normalize_email(email)) user.set_password(password) user.save(using=self._db) return user def create_superuser(self, email, password): u = self.create_user(email, password=password) u.is_admin = True u.save(using=self._db) return u class MyUser(AbstractBaseUser): email = models.EmailField(_('e-mail address'), unique=True, db_index=True) first_name = models.CharField(_('first name'), max_length=30, blank=True) last_name = models.CharField(_('last name'), max_length=30, blank=True) objects = MyUserManager() USERNAME_FIELD = 'email' REQUIRED_FIELDS = []
これでユーザー登録は通った。
起動して/accounts/loginをみてみる
今度はregistration-defaultsのテンプレートのurl関数でエラーに。1.5で変わったんでしたね。
NoReverseMatch at /accounts/login/ 'url' requires a non-empty first argument. The syntax changed in Django 1.5, see the docs.
/accounts/loginの場合、registration/login.htmlの以下の箇所でエラーになる。
<form method="post" action="{% url django.contrib.auth.views.login %}">{% csrf_token %}
INSTALLED_APPSからregistration-defaultsは外して、テンプレートをプロジェクトのTEMPLATE_DIRにコピーして修正する。
urlを使ってるところは全部修正しないといけない。
これでとりあえずログインは見れるようになった。
ちゃんとemailをログインに使うようになってる。
ログインできること、不正なパラメータでログイン失敗すること、/accounts/logoutでログアウトできることを確認できた。