django admin框架使用系列之三:扩展user model
By:Roy.LiuLast updated:2012-12-20
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的类:
还需要修改admin.py
修改settings.py 的配置,增加
按照官方的解释,这里是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
用这种方式 可以直接用user = CustomUser.objects.create(...)方式创建新对象. 而且如果用request.user得到的就是你扩展的这个对象,可以直接取属性的。不需要get_profile.
2.扩展认证机制
3. 配置settings.py
4. 运行 python manage.py syncdb
同样也会生成一个数据库,不过表的字段与前面一种方法有所不用。
然后运行,同样测试,可以达到同样的效果,但界面上密码输入哪里我始终不满意,所以就没采用。
第三种方法的源码如下:
点击下载此文件
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
同样也会生成一个数据库,不过表的字段与前面一种方法有所不用。
然后运行,同样测试,可以达到同样的效果,但界面上密码输入哪里我始终不满意,所以就没采用。
第三种方法的源码如下:
点击下载此文件
From:一号门
Previous:django admin框架使用系列之二:注册自定义类,并配置显示样式
Next:第一次尝试视频托管服务(盛大云与酷6网)
COMMENTS