django自定义User模型(xadmin)

继承AbstractBaseUser类

继承PermissionsMixin类是因为想要,该类中的is_superuser字段,并且xadmin需要里面的 user_permissions 和groups 字段用来添加权限,和组

class UserProfile(AbstractBaseUser, PermissionsMixin):
    """
    用户
    """
    username = models.CharField('用户名', max_length=30, unique=True)
    alias = models.CharField('姓名', max_length=50, default='')
    birthday = models.DateField(null=True, blank=True, verbose_name="出生年月")
    gender = models.CharField(max_length=6, choices=(("male", u"男"), ("female", "女")), default="female",
                              verbose_name="性别")
    nation = models.CharField(null=True, blank=True, max_length=15, verbose_name="汉族", help_text="汉族")
    education = models.CharField(null=True, blank=True, max_length=15, verbose_name="学历", help_text="学历")
    id_number = models.CharField(null=True, blank=True, max_length=15, verbose_name="身份证", help_text="身份证")
    mobile = models.CharField(null=True, blank=True, max_length=11, verbose_name="电话", help_text="电话")
    email = models.EmailField(max_length=100, null=True, blank=True, verbose_name="邮箱", help_text="邮箱")
    address = models.CharField(null=True, blank=True, max_length=50, verbose_name="家庭地址", help_text="家庭地址")
    head_picture = models.ImageField(max_length=200, upload_to="users/images/headpicture/%Y/%m", null=True,
                                     blank=True, )
    dept_id = models.IntegerField('部门id', default=0)
    is_active = models.BooleanField('已激活', default=True)
    gmt_created = models.DateTimeField('创建时间', default=datetime.now)
    gmt_modified = models.DateTimeField(verbose_name=u'更新时间', auto_now=True)
    is_deleted = models.BooleanField('已删除', default=False)

    objects = UserManager()
    USERNAME_FIELD = 'username' #描述用户模型上用作唯一标识符的字段名称的字符串
    REQUIRED_FIELDS = ['email']

    @property
    def is_staff(self):
        return self.is_active

    def get_short_name(self):
        return self.username

    def get_alias_name(self):
        return self.alias

    def has_perm(self, perm, obj=None):
        "Does the user have a specific permission?"
        # Simplest possible answer: Yes, always
        return True

    def has_perms(self, perm, obj=None):
        return True

    def has_module_perms(self, app_label):
        return True

    @property
    def dept_name(self):
        dept_id = self.dept_id
        dept_object = LoonDept.objects.filter(id=dept_id)
        if dept_object:
            return dept_object[0].name
        else:
            return '部门id不存在'

    class Meta:
        verbose_name = '用户'
        verbose_name_plural = '用户'

    def __str__(self):
        return self.username
USERNAME_FIELD

描述用户模型上作为唯一标识符的字段名称的字符串。该字段必须是唯一的(即:unique=True);

REQUIRED_FIELDS

通过createsuperuser管理命令创建用户时将提示的字段名称列表。系统将提示用户为每个字段提供值。它必须包含任何blankFalse定义或未定义的字段,并且可能包含在交互式创建用户时要提示的其他字段。 REQUIRED_FIELDS对Django的其他部分没有影响,比如在管理员中创建用户。

is_active

一个布尔属性,指示用户是否被视为“活动”。此属性作为AbstractBaseUser默认属性提供 True

我还必须定义我自己的UserManager。这是因为现有的管理器定义了create_user和create_superuser方法。

所以现在我的UserManager是这样的:

class UserManager(BaseUserManager):

    def create_user(self, email, username, password=None, dep=0):
        if not email:
            raise ValueError("Users must have an email address")
        user = self.model(username=username, email=self.normalize_email(email))
        user.save(using=self._db)
        return user

    def create_superuser(self, email, username, password):
        user = self.create_user(email=self.normalize_email(email), username=username, password=password)
        user.is_superuser = True
        user.save(using=self._db)
        return user

我们现在已经清除了一些不想要的字段,比如is_staff, short_name...

现在,我们必须更新我们的settings.py。更具体地说,是AUTH_USER_MODEL属性

AUTH_USER_MODEL = 'users.UserProfile'

引入User模型

方法一

from django.contrib.auth import get_user_model
  User = get_user_model()

方法二

例子

from django.conf import settings
from django.db import models

class Article(models.Model):
    author = models.ForeignKey(
        settings.AUTH_USER_MODEL,
        on_delete=models.CASCADE,
    )

xadmin中使用自定义模型

adminx.py

import xadmin
from xadmin import views
from apps.loon_model_base_admin import UserModelBaseAdmin
from .models import UserProfile
from django.contrib.auth.forms import (UserCreationForm, UserChangeForm,)
from xadmin.layout import Fieldset, Main, Side
from django.forms import ModelMultipleChoiceField
from django.utils.translation import ugettext as _


ACTION_NAME = {
    'add': _('Can add %s'),
    'change': _('Can change %s'),
    'edit': _('Can edit %s'),
    'delete': _('Can delete %s'),
    'view': _('Can view %s'),
}


def get_permission_name(p):
    action = p.codename.split('_')[0]
    if action in ACTION_NAME:
        return ACTION_NAME[action] % str(p.content_type)
    else:
        return p.name


class PermissionModelMultipleChoiceField(ModelMultipleChoiceField):

    def label_from_instance(self, p):
        return get_permission_name(p)

class UserFZAdmin(object):
    # change_user_password_template = None
    list_display = ('id', 'username', 'alias','gender', 'email', 'mobile', 'dept_id', 'is_active', 'is_superuser') + UserModelBaseAdmin.list_display
    list_filter = ('is_superuser', 'is_active')
    readonly_fields = ['last_login']
    search_fields = ('username',)
    model_icon = 'fa fa-user'
    relfield_style = 'fk-ajax'
    style_fields = {'user_permissions': 'm2m_transfer'}

    def get_model_form(self, **kwargs):
        if self.org_obj is None:
            self.form = UserCreationForm
        else:
            self.form = UserChangeForm
        return super(UserFZAdmin, self).get_model_form(**kwargs)

    def get_field_attrs(self, db_field, **kwargs):
        attrs = super(UserFZAdmin, self).get_field_attrs(db_field, **kwargs)
        if db_field.name == 'user_permissions':
            attrs['form_class'] = PermissionModelMultipleChoiceField
        return attrs

    def get_form_layout(self):
        if self.org_obj:
            self.form_layout = (
                Main(
                    Fieldset('',
                             'username', 'password',
                             css_class='unsort no_title'
                             ),
                    Fieldset('其他字段',
                             'alias','birthday', 'gender', 'nation', 'education', 'id_number',
                             'mobile','email', 'id_number', 'address', 'head_picture', 'head_picture',
                             'dept_id','head_picture', 'gmt_created', 'gmt_modified', 'last_login'
                             ),
                    Fieldset(_('Permissions'),
                             'groups', 'user_permissions'
                             ),
                ),
                Side(
                    Fieldset(('Status'),
                             'is_active', 'is_superuser','is_deleted'
                             ),
                )
            )
        return super(UserFZAdmin, self).get_form_layout()

xadmin.site.register(UserProfile, UserFZAdmin)

这些代码是模仿
xadmin->plugins->auth.py 研究一下源码会比较好理解

现在xadmin启动服务器会报错,因为xadmin已经把User注册到xadmin里了
xadmin.sites.AlreadyRegistered: The model UserProfile is already registered
现在需要把xadmin.plugins.auth 下的UserAdmin注册注释掉

运行xadmin查看页面


xadmin

想要的定制的User就与xadmin关联上了

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 156,907评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,546评论 1 289
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 106,705评论 0 238
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,624评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 51,940评论 3 285
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,371评论 1 210
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,672评论 2 310
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,396评论 0 195
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,069评论 1 238
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,350评论 2 242
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,876评论 1 256
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,243评论 2 251
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,847评论 3 231
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,004评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,755评论 0 192
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,378评论 2 269
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,266评论 2 259