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  ,就可能有麻烦

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
同样也会生成一个数据库,不过表的字段与前面一种方法有所不用。

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

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

上一篇: django admin框架使用系列之二:注册自定义类,并配置显示样式
下一篇: 第一次尝试视频托管服务(盛大云与酷6网)
 评论 ( What Do You Think )
名称
邮箱
网址
评论
验证
   
 

 


  • 微信公众号

  • 我的微信

站点声明:

1、一号门博客CMS,由Python, MySQL, Nginx, Wsgi 强力驱动

2、部分文章或者资源来源于互联网, 有时候很难判断是否侵权, 若有侵权, 请联系邮箱:summer@yihaomen.com, 同时欢迎大家注册用户,主动发布无版权争议的 文章/资源.

3、鄂ICP备14001754号-3, 鄂公网安备 42280202422812号