django admin框架使用系列之三:扩展user model

django 自带的权限框架,其中auth_user表的字段,很难满足正常的需求,因此需要扩展,至于扩展,一般有如下几种选择:
1. 直接修改django 源码,修改User class 的定义,以及各种方法等,然后把数据库auth_user表里的字段扩展到与自己需求一致.(源代码在:django.contrib.auth.models import User),这种方式,每次升级django都得很小心.

2. 把django 的user以及认证部分的源代码拷贝到自己的app下面,然后修改,配置,这样就不需要改动django的代码了.但如果你要升级django  ,就可能有麻烦

3. 继承User,做扩展.

4. django 官方推荐的方法,profile 方式扩展.

比较一下这几种方式,发现,1,2种方法很黄很暴力.所以不是在非常特殊的情况下,建议不用。第3中方法,我目前测试下来是可以,但扩展之后,输入密码的时候,居然是明文的,而且保存进数据库是没有经过加密的密码,目前还在找原因,所以这里介绍第4种方法.

在models.py 中增加如下扩展user的类:
程序代码 程序代码

#==================扩展用户====================================
class UserProfile(models.Model):
    user = models.OneToOneField(User)    
    major = models.TextField(default='', blank=True)
    address = models.CharField(max_length=200,default='',blank=True)
    
    def __unicode__(self):
        return self.user.username

def create_user_profile(sender, instance, created, **kwargs):
    """Create the UserProfile when a new User is saved"""
    if created:
        profile = UserProfile()
        profile.user = instance
        profile.save()

#post_save.connect(create_user_profile, sender=User)
""" 不明白的是,我一定注释掉上面这一行,才不会出错,否则会有Duplicate entry '2' for key 'user_id'") ,看意思是,重复了,但不明白为什么重复,注释掉上面的之后,一切正常,但与官方文档又有差异了,迷惑中"""
#==================扩展用户结束================================


还需要修改admin.py
程序代码 程序代码

"""用户模块扩展"""
class ProfileInline(admin.StackedInline):
    model = UserProfile
    #fk_name = 'user'
    max_num = 1
    can_delete = False

class CustomUserAdmin(UserAdmin):
    inlines = [ProfileInline,]

admin.site.unregister(User)
admin.site.register(User, CustomUserAdmin)
"""用户模块扩展"""


修改settings.py 的配置,增加
程序代码 程序代码

"""用户模块扩展部分"""
AUTH_PROFILE_MODULE = 'djangoadmin.myadmin.UserProfile'
"""用户模块扩展完成"""

按照官方的解释,这里是app label加上扩展类的名字. 应该也就是创建的app的名字,官方推荐的方式就两个部分用"."连接起来,我这里有三个部分,也没有报错。
[/code]

然后运行 python manage.py syncdb ,这是会在数据库中创建响应的表,并且有user_id这个外键字段.

最后,我们来运行一下程序,并进入到增加用户界面中,你会发现,你扩展的字段都显示出来了



每次增加用户,都会在扩展的表中增加相应的数据,修改的时候,也会修改响相应的数据,通过 user_id 来关联,这样就完成了user model的扩展。

如果要获取扩展表中的内容,可以通过 request.user.get_profile().address 这种方式来获取. 得到 User对象后,就能很方便的得到扩展的类.

********************分割线************************************

如果想通过继承User的方式来做的,可以用如下方法,转载自网上:
1.创建 user profile 类,直接继承于 User
程序代码 程序代码

from django.contrib.auth.models import User, UserManager
class CustomUser(User):
    timezone = models.CharField(max_length=50, default='Asia/shanghai')  
    objects = UserManager()

用这种方式 可以直接用user = CustomUser.objects.create(...)方式创建新对象. 而且如果用request.user得到的就是你扩展的这个对象,可以直接取属性的。不需要get_profile.

2.扩展认证机制
程序代码 程序代码

from django.conf import settings
from django.contrib.auth.backends import ModelBackend
from django.core.exceptions import ImproperlyConfigured
from django.db.models import get_model

class CustomUserModelBackend(ModelBackend):
    def authenticate(self, username=None, password=None):
        try:
            user = self.user_class.objects.get(username=username)
            if user.check_password(password):
                return user
        except self.user_class.DoesNotExist:
            return None

    def get_user(self, user_id):
        try:
            return self.user_class.objects.get(pk=user_id)
        except self.user_class.DoesNotExist:
            return None

    @property
    def user_class(self):
        if not hasattr(self, '_user_class'):
            self._user_class = get_model(*settings.CUSTOM_USER_MODEL.split('.', 2))
            if not self._user_class:
                raise ImproperlyConfigured('Could not get custom user model')
        return self._user_class


3. 配置settings.py
程序代码 程序代码

AUTHENTICATION_BACKENDS = (
    'myproject.auth_backends.CustomUserModelBackend',
)


4. 运行 python manage.py syncdb
同样也会生成一个数据库,不过表的字段与前面一种方法有所不用。

然后运行,同样测试,可以达到同样的效果,但界面上密码输入哪里我始终不满意,所以就没采用。

第三种方法的源码如下:
下载文件 点击下载此文件


除非申明,文章均为一号门原创,转载请注明本文地址,谢谢!
[本日志由 轻舞肥羊 于 2012-12-20 08:53 PM 编辑]
文章来自: 本站原创
引用通告: 查看所有引用 | 我要引用此文章
Tags: django admin
相关日志:
评论: 0 | 引用: 0 | 查看次数: -
发表评论
昵 称:
密 码: 游客发言不需要密码.
内 容:
验证码: 验证码
选 项:
虽然发表评论不用注册,但是为了保护您的发言权,建议您注册帐号.