/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')
添加用户页面
修改用户页面
如果不让管理员修改用户信息可以通过设置权限限制