首页 > Python > django > django中如何扩展User表的字段
2017
08-10

django中如何扩展User表的字段

在前一段时间做开发的时候,碰到一个case,要求在User表中增加一个字段,我当时想了一想,想出了以下几法:

  1. 第一反应就是,既然是扩展django自带的model表,当然只有去修改django的源代码了,加个字段一句话的事。但是想到此招不行,修改源码乃是大忌,因为这不利于项目的迁移以及django的版本升级;
  2. 那我把django 的user以及认证部分的源代码拷贝到自己的app下面,然后修改,配置,这样就不需要改动django的代码了,我傻啊,为了加一字段,搞出这么大一动静;
  3. 那我就自定义一个表呗,然后和User表做个关联,每次有关User表的操作,我就同步到新建的表,在我的项目中呢,我就用我自定义的表,不就ok了嘛,但是此法一是比较麻烦,得把之前和User有关的都改到新表,另外就是每次都得同步,比较耗资源;
  4. 这个方法是官方推崇的办法,profile 方式扩展.,大体思路是创建 user profile 类,直接继承于 User ,然后扩展扩展认证机制,再在setting中,修改AUTHENTICATION_BACKENDS为你新建的认证机制,这样就用你继承的新的User表,代替了Django的User表,以后所有有关User的操作都用这张表即可,听起来似乎不错,但我不还得修改之前和User相关的代码么。

要是能有这么一种方法,能在不修改源码,不增加新表的情况下,就能扩展User表,想必那是极好的。经过多番搜索,找到了一种通过元类来达到目的的方法,现分享给大伙:

 

这样就大功告成啦!!!

稍微解释一下这段代码: ProfileBase是自定义的一个元类,继承自types.ClassType,其中ProfileUser为一个基类,其元类为ProfileBase,而ExtraInfo才是我们真正自定义字段的类,之所以把基类ProfileUser和ExtraInfo分开,是为了便于在其他地方引用ProfileUser,进行自定义扩展。简单说来,当解释器看到你在定义一个ProfileUser类的子类,而ProfileUser类的元类是ProfileBase,所以ExtraInfo的元类也是ProfileBase,在定义ProfileUser的子类的时候,它就会执行元类ProfileBase中的new中代码,并且将正在定义的类的(名字,基类,类属性)作为参数传递给new,这里的name就是类名ExtraInfo,attrs中则包含你新加的字段,通过User.add_to_class把新的字段加入到User中,为了能在admin中显示出来,把它加入到UserAdmin.fieldsets中,这样就能在后台编辑这个这个字段,当然,你也可以加入到ist_display,使之在列表中显示。

如果你有其他app也想往User Model中加field或方法,都只要通过子类ProfileUser类,然后使用声明语法进行定义即可,所有其他工作都有元类帮你完成。这也是所有django的model的内部工作,你可以用此方法扩展任何model。

转载请注明出处:http://www.opscoder.info/extend_user.html

最后编辑:
作者:hanxin
从前有个人关注了我,结果那一年开始ta走向了人生的巅峰!

留下一个回复

你的email不会被公开。