Django rest framework 重写 xadmin 后台(自定义登录功能)

 /Users/makchikin/Downloads/cgmine/apps/users/adminx.py

import unicodedata

from django import forms
from django.contrib.auth import (
    get_user_model, password_validation,
)
from django.contrib.auth.hashers import (
    UNUSABLE_PASSWORD_PREFIX, identify_hasher,
)
from django.forms import ModelMultipleChoiceField
from django.utils.translation import gettext, gettext_lazy as _
from django.utils.translation import ugettext as _

import xadmin
from apps.users.models import UserDetailInline
from apps.users.models import UserProfile
from apps.utils.uid import UID
from xadmin import views
from xadmin.layout import Fieldset, Main, Side

UserModel = get_user_model()



class BaseSetting(object):
    enable_themes = True
    use_bootswatch = True


class GlobalSettings(object):
    site_title = "CG Mine"
    site_footer = "CG Mine Studio@2019 copyright"
    # menu_style = "accordion"


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 UsernameField(forms.CharField):
    def to_python(self, value):
        return unicodedata.normalize('NFKC', super().to_python(value))

class ReadOnlyPasswordHashWidget(forms.Widget):
    template_name = 'auth/widgets/read_only_password_hash.html'
    read_only = True

    def get_context(self, name, value, attrs):
        context = super().get_context(name, value, attrs)
        summary = []
        if not value or value.startswith(UNUSABLE_PASSWORD_PREFIX):
            summary.append({'label': gettext("No password set.")})
        else:
            try:
                hasher = identify_hasher(value)
            except ValueError:
                summary.append({'label': gettext("Invalid password format or unknown hashing algorithm.")})
            else:
                for key, value_ in hasher.safe_summary(value).items():
                    summary.append({'label': gettext(key), 'value': value_})
        context['summary'] = summary
        return context

class ReadOnlyPasswordHashField(forms.Field):
    widget = ReadOnlyPasswordHashWidget

    def __init__(self, *args, **kwargs):
        kwargs.setdefault("required", False)
        super().__init__(*args, **kwargs)

    def bound_data(self, data, initial):
        # Always return initial because the widget doesn't
        # render an input field.
        return initial

    def has_changed(self, initial, data):
        return False

class UserCreationForm(forms.ModelForm):
    """
    xadmin后台新建用户表单。
    """
    error_messages = {
        'password_mismatch': _("The two password fields didn't match."),
    }
    password1 = forms.CharField(
        label=_("Password"),
        strip=False,
        widget=forms.PasswordInput,
        help_text=password_validation.password_validators_help_text_html(),
    )
    password2 = forms.CharField(
        label=_("Password confirmation"),
        widget=forms.PasswordInput,
        strip=False,
        help_text=_("Enter the same password as before, for verification."),
    )
    # 重写后台注册--------------------------------------------
    username = forms.CharField(label='用户名', max_length=50, required=True, help_text=_(r'50个字符或更少。仅支持字母、数字和@/./+/-/_'), )
    cellphone = forms.CharField(label='手机', max_length=11, min_length=11, required=True, help_text=_(r'请填写国内11位手机号码'), )

    class Meta:
        # model = User
        # 加载自定义模型--------------------------------------------
        model = UserModel
        fields = ("username", "cellphone")
        field_classes = {'username': UsernameField, "cellphone": UsernameField}

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if self._meta.model.USERNAME_FIELD in self.fields:
            self.fields[self._meta.model.USERNAME_FIELD].widget.attrs.update({'autofocus': True})

    def clean_password2(self):
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError(
                self.error_messages['password_mismatch'],
                code='password_mismatch',
            )
        return password2

    def _post_clean(self):
        super()._post_clean()
        # Validate the password after self.instance is updated with form data
        # by super().
        password = self.cleaned_data.get('password2')
        if password:
            try:
                password_validation.validate_password(password, self.instance)
            except forms.ValidationError as error:
                self.add_error('password2', error)

    def set_uid(self):
        '''设置uid'''
        # --------------------------------------------
        uid = UID().get_uid()
        if UserModel.objects.filter(uid=uid).count() == 0:
            return uid
        else:
            self.set_uid()

    def save(self, commit=True):
        '''保存数据'''
        user = super().save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        # 保存手机和UID--------------------------------------------
        user.cellphone = (self.cleaned_data["cellphone"])
        user.uid = self.set_uid()
        if commit:
            user.save()
        return user


class UserChangeForm(forms.ModelForm):
    '''xadmin后台修改用户表单'''
    # 增加username为必须字段-----------------------------------------
    username = forms.CharField(label='用户名', max_length=50, required=True, help_text=_(r'50个字符或更少。仅支持字母、数字和@/./+/-/_'), )
    password = ReadOnlyPasswordHashField(
        label=_("Password"),
        help_text=_(
            "Raw passwords are not stored, so there is no way to see this "
            "user's password, but you can change the password using "
            "<a href=\"{}\">this form</a>."
        ),
    )

    class Meta:
        model = UserModel
        fields = '__all__'
        field_classes = {'username': UsernameField}

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        password = self.fields.get('password')
        if password:
            password.help_text = password.help_text.format('../password/')
        user_permissions = self.fields.get('user_permissions')
        if user_permissions:
            user_permissions.queryset = user_permissions.queryset.select_related('content_type')

    def clean_password(self):
        # Regardless of what the user provides, return the initial value.
        # This is done here, rather than on the field, because the
        # field does not have access to the initial value
        return self.initial.get('password')


class UserProfileAdmin(object):
    list_display = ['id', 'username', 'cellphone', 'is_active', 'is_staff', 'is_superuser', 'date_joined', ]
    list_display_links = ['username']
    search_fields = ['username', 'cellphone', 'date_joined', ]
    list_filter = ['username', 'cellphone', 'date_joined', 'is_superuser', 'is_active', ]
    list_editable = ['is_active', 'is_staff', 'is_superuser', ]
    readonly_fields = ['uid', ]
    ordering = ('-id',)
    model_icon = 'fa fa-user'
    relfield_style = 'fk-ajax'
    style_fields = {'user_permissions': 'm2m_transfer'}
    inlines = [UserDetailInline]

    # 修改xadmin后台页面: UserCreationForm / UserChangeForm
    # /Users/makchikin/.virtualenvs/cgmine/lib/python3.7/site-packages/django/contrib/auth/forms.py
    def get_model_form(self, **kwargs):
        if self.org_obj is None:
            self.form = UserCreationForm
        else:
            self.form = UserChangeForm
        return super(UserProfileAdmin, self).get_model_form(**kwargs)

    def get_field_attrs(self, db_field, **kwargs):
        attrs = super(UserProfileAdmin, 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', 'cellphone', 'password',
                             css_class='unsort no_title'
                             ),
                    Fieldset('其他信息',
                             'uid', 'last_name', 'first_name', 'email', 'last_login', 'date_joined',
                             ),
                    Fieldset(_('用户权限'),
                             'groups', 'user_permissions'
                             ),
                ),
                Side(
                    Fieldset(('用户状态'),
                             'is_active', 'is_staff', 'is_superuser',
                             ),
                )
            )
        return super(UserProfileAdmin, self).get_form_layout()


xadmin.site.register(UserProfile, UserProfileAdmin)
xadmin.site.register(views.BaseAdminView, BaseSetting)
xadmin.site.register(views.CommAdminView, GlobalSettings)

.virtualenvs/cgmine/lib/python3.7/site-packages/django/contrib/auth/forms.py(此处是原文件参考)

class UserCreationForm(forms.ModelForm):
    """
    A form that creates a user, with no privileges, from the given username and password.
    一种从给定的用户名和密码创建没有权限的用户的表单。
    """
    error_messages = {
        'password_mismatch': _("The two password fields didn't match."),
    }
    password1 = forms.CharField(
        label=_("Password"),
        strip=False,
        widget=forms.PasswordInput,
        help_text=password_validation.password_validators_help_text_html(),
    )
    password2 = forms.CharField(
        label=_("Password confirmation"),
        widget=forms.PasswordInput,
        strip=False,
        help_text=_("Enter the same password as before, for verification."),
    )
    # 重写后台注册--------------------------------------------
    username = forms.CharField(label='用户名', max_length=50, required=True, help_text=_(r'50个字符或更少。仅支持字母、数字和@/./+/-/_'), )
    cellphone = forms.CharField(label='手机', max_length=11, min_length=11, required=True, help_text=_(r'请填写国内11位手机号码'), )

    class Meta:
        # model = User
        # 加载自定义模型--------------------------------------------
        model = UserModel
        fields = ("username", "cellphone")
        field_classes = {'username': UsernameField, "cellphone": UsernameField}

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        if self._meta.model.USERNAME_FIELD in self.fields:
            self.fields[self._meta.model.USERNAME_FIELD].widget.attrs.update({'autofocus': True})

    def clean_password2(self):
        password1 = self.cleaned_data.get("password1")
        password2 = self.cleaned_data.get("password2")
        if password1 and password2 and password1 != password2:
            raise forms.ValidationError(
                self.error_messages['password_mismatch'],
                code='password_mismatch',
            )
        return password2

    def _post_clean(self):
        super()._post_clean()
        # Validate the password after self.instance is updated with form data
        # by super().
        password = self.cleaned_data.get('password2')
        if password:
            try:
                password_validation.validate_password(password, self.instance)
            except forms.ValidationError as error:
                self.add_error('password2', error)

    def set_uid(self):
        '''设置uid'''
        # --------------------------------------------
        uid = UID().get_uid()
        if UserModel.objects.filter(uid=uid).count() == 0:
            return uid
        else:
            self.set_uid()

    def save(self, commit=True):
        '''保存数据'''
        user = super().save(commit=False)
        user.set_password(self.cleaned_data["password1"])
        # 保存手机和UID--------------------------------------------
        user.cellphone = (self.cleaned_data["cellphone"])
        user.uid = self.set_uid()
        if commit:
            user.save()
        return user


class UserChangeForm(forms.ModelForm):
    '''重新修改页面'''
    # 增加username为必须字段-----------------------------------------
    username = forms.CharField(label='用户名', max_length=50, required=True, help_text=_(r'50个字符或更少。仅支持字母、数字和@/./+/-/_'), )
    password = ReadOnlyPasswordHashField(
        label=_("Password"),
        help_text=_(
            "Raw passwords are not stored, so there is no way to see this "
            "user's password, but you can change the password using "
            "<a href=\"{}\">this form</a>."
        ),
    )

    class Meta:
        model = UserModel
        fields = '__all__'
        field_classes = {'username': UsernameField}

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        password = self.fields.get('password')
        if password:
            password.help_text = password.help_text.format('../password/')
        user_permissions = self.fields.get('user_permissions')
        if user_permissions:
            user_permissions.queryset = user_permissions.queryset.select_related('content_type')

    def clean_password(self):
        # Regardless of what the user provides, return the initial value.
        # This is done here, rather than on the field, because the
        # field does not have access to the initial value
        return self.initial.get('password')

添加用户页面 

修改用户页面

如果不让管理员修改用户信息可以通过设置权限限制 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值