cloverrose's blog

Python, Machine learning, Emacs, CI/CD, Webアプリなど

Django ユーザープロファイルを作成

https://docs.djangoproject.com/en/1.4/topics/auth/#storing-additional-information-about-users

を参考にTwitterのscreen_nameとnameをUserに紐付けることを考える。

注意点

Userプロファイルはひとつしか設定できない
AUTH_PROFILE_MODULEに複数指定するとエラーとなり、
AUTH_PROFILE_MODULEを複数定義すると、最後に定義した値になる

前はForeignKey(User, unique=True)で定義してたけど、公式ドキュメントの方法に変更(2012/6/19)

やること

Userプロファイル用のモデルを作成するためにmodels.pyを編集

from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save


class UserProfile(models.Model):
    user = models.OneToOneField(User)

    # Additional information about User
    screen_name = models.CharField(max_length=255)
    name = models.CharField(max_length=255)


def create_user_profile(sender, instance, created, **kwargs):
    """
    if user is created (or changed),
    then create user profile about the user, using signal

    kwargs contains such key 'raw', 'signal', 'using'
    """

    if created:
        # user is created, not changed
        UserProfile.objects.create(user=instance)

post_save.connect(create_user_profile, sender=User)

ユーザープロファイルを反映させるためにsettings.pyを編集

新しくAUTH_PROFILE_MODULEを設定

AUTH_PROFILE_MODULE='accounts.UserProfile'

新規ユーザーを作る時に次のようにして、設定

new_user = User.objects.create_user('username', '', 'password')
# create_user_profileによって作成と同時にUserProfileも作成されている
# よって後は値を設定すればいい

# set profile twitter screen_name and name
profile = new_user.get_profile()
profile.screen_name = 'screen_name'
profile.name = 'name'
profile.save()


これによって、

usr=User.objects.get(username='username')
prof=usr.get_profile()
prof.screen_name # => u'screen_name'
prof.name # => u'name'

というようにget_profile()が使えるようになる。


次にAdminサイトをカスタマイズ

adminサイトのauth/userにプロファイル情報を表示するために、admin.pyを編集

from django.contrib import admin
from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin
from mysite.question.models import UserProfile

class UserProfileInline(admin.StackedInline):
    model = UserProfile
    extra = 0

class MyUserAdmin(UserAdmin):
    inlines = UserAdmin.inlines + [UserProfileInline]

admin.site.unregister(User)
admin.site.register(User, MyUserAdmin)

memo

StackedInlineで設定しそうな項目
can_delete
extra
fields
model
queryset



突如あらわれた謎のエラー

http://stackoverflow.com/questions/6388105/django-integrityerror-column-user-id-is-not-unique
を参考に解決
でも、なぜこれでいいのか・なぜエラーが突然はっせいしだしたのかがわかっていない