|
|
|
|
@ -1,47 +1,100 @@
|
|
|
|
|
from django.contrib import admin
|
|
|
|
|
from django.urls import reverse
|
|
|
|
|
from django.utils.html import format_html
|
|
|
|
|
from django.utils.translation import gettext_lazy as _
|
|
|
|
|
#django核心组件导入
|
|
|
|
|
from django import forms# Django 表单处理模块
|
|
|
|
|
from django.contrib.auth.admin import UserAdmin # Django 默认用户管理后台类
|
|
|
|
|
from django.contrib.auth.forms import UserChangeForm # 用户信息修改表单基类
|
|
|
|
|
from django.contrib.auth.forms import UsernameField# 用户名专用表单字段
|
|
|
|
|
from django.utils.translation import gettext_lazy as _ # 国际化翻译函数
|
|
|
|
|
|
|
|
|
|
# 本地应用导入
|
|
|
|
|
# Register your models here.
|
|
|
|
|
from .models import BlogUser # 导入自定义用户模型
|
|
|
|
|
|
|
|
|
|
def disable_commentstatus(modeladmin, request, queryset):
|
|
|
|
|
queryset.update(is_enable=False)
|
|
|
|
|
|
|
|
|
|
class BlogUserCreationForm(forms.ModelForm):
|
|
|
|
|
"""
|
|
|
|
|
自定义用户创建表单(用于管理后台添加新用户)
|
|
|
|
|
继承自 ModelForm专门处理 BlogUser 模型的创建
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
def enable_commentstatus(modeladmin, request, queryset):
|
|
|
|
|
queryset.update(is_enable=True)
|
|
|
|
|
# 定义密码输入字段(需要输入两次以确保一致)
|
|
|
|
|
password1 = forms.CharField(label=_('password'), # 字段标签(支持国际化)
|
|
|
|
|
widget=forms.PasswordInput) # 密码输入控件
|
|
|
|
|
password2 = forms.CharField(label=_('Enter password again'), # 确认密码标签
|
|
|
|
|
widget=forms.PasswordInput) # 密码输入控件
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
model = BlogUser# 关联的模型类
|
|
|
|
|
fields = ('email',)# 创建用户时显示的字段(这里只显示email字段)
|
|
|
|
|
|
|
|
|
|
disable_commentstatus.short_description = _('Disable comments')
|
|
|
|
|
enable_commentstatus.short_description = _('Enable comments')
|
|
|
|
|
def clean_password2(self):
|
|
|
|
|
"""
|
|
|
|
|
验证两次输入的密码是否一致
|
|
|
|
|
Django 表单验证方法,方法名必须以 clean_ 开头
|
|
|
|
|
"""
|
|
|
|
|
# Check that the two password entries match
|
|
|
|
|
password1 = self.cleaned_data.get("password1")# 获取第一次输入的密码
|
|
|
|
|
password2 = self.cleaned_data.get("password2")# 获取第二次输入的密码
|
|
|
|
|
# 如果两次密码不一致,抛出验证错误
|
|
|
|
|
if password1 and password2 and password1 != password2:
|
|
|
|
|
raise forms.ValidationError(_("passwords do not match"))# 错误信息(支持国际化)
|
|
|
|
|
return password2# 返回验证后的值
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CommentAdmin(admin.ModelAdmin):
|
|
|
|
|
list_per_page = 20
|
|
|
|
|
def save(self, commit=True):
|
|
|
|
|
"""
|
|
|
|
|
重写保存方法,在保存用户前处理密码哈希
|
|
|
|
|
"""
|
|
|
|
|
# Save the provided password in hashed format
|
|
|
|
|
user = super().save(commit=False) # 调用父类保存方法但不提交到数据库
|
|
|
|
|
user.set_password(self.cleaned_data["password1"]) # 对密码进行哈希加密
|
|
|
|
|
if commit:
|
|
|
|
|
user.source = 'adminsite' # 设置用户来源标记(表示通过管理后台创建)
|
|
|
|
|
user.save()# 保存到数据库
|
|
|
|
|
return user# 返回用户对象
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class BlogUserChangeForm(UserChangeForm):
|
|
|
|
|
"""
|
|
|
|
|
自定义用户信息修改表单(用于管理后台编辑用户)
|
|
|
|
|
继承自 Django 自带的 UserChangeForm
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
|
model = BlogUser # 关联的模型类
|
|
|
|
|
fields = '__all__'# 显示所有字段
|
|
|
|
|
field_classes = {'username': UsernameField}# 指定用户名使用专用字段类型
|
|
|
|
|
|
|
|
|
|
def __init__(self, *args, **kwargs):
|
|
|
|
|
"""
|
|
|
|
|
表单初始化方法
|
|
|
|
|
可以在这里对表单字段进行自定义设置
|
|
|
|
|
"""
|
|
|
|
|
super().__init__(*args, **kwargs) # 调用父类初始化方法
|
|
|
|
|
# 可以在这里添加自定义逻辑,如修改字段属性等
|
|
|
|
|
|
|
|
|
|
class BlogUserAdmin(UserAdmin):
|
|
|
|
|
"""
|
|
|
|
|
自定义用户管理后台配置
|
|
|
|
|
继承自 Django 自带的 UserAdmin
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
# 指定使用的表单类
|
|
|
|
|
form = BlogUserChangeForm # 编辑用户时使用的表单
|
|
|
|
|
add_form = BlogUserCreationForm# 添加用户时使用的表单
|
|
|
|
|
|
|
|
|
|
# 管理后台列表页显示配置
|
|
|
|
|
list_display = (
|
|
|
|
|
'id',
|
|
|
|
|
'body',
|
|
|
|
|
'link_to_userinfo',
|
|
|
|
|
'link_to_article',
|
|
|
|
|
'is_enable',
|
|
|
|
|
'creation_time')
|
|
|
|
|
list_display_links = ('id', 'body', 'is_enable')
|
|
|
|
|
list_filter = ('is_enable',)
|
|
|
|
|
exclude = ('creation_time', 'last_modify_time')
|
|
|
|
|
actions = [disable_commentstatus, enable_commentstatus]
|
|
|
|
|
|
|
|
|
|
def link_to_userinfo(self, obj):
|
|
|
|
|
info = (obj.author._meta.app_label, obj.author._meta.model_name)
|
|
|
|
|
link = reverse('admin:%s_%s_change' % info, args=(obj.author.id,))
|
|
|
|
|
return format_html(
|
|
|
|
|
u'<a href="%s">%s</a>' %
|
|
|
|
|
(link, obj.author.nickname if obj.author.nickname else obj.author.email))
|
|
|
|
|
|
|
|
|
|
def link_to_article(self, obj):
|
|
|
|
|
info = (obj.article._meta.app_label, obj.article._meta.model_name)
|
|
|
|
|
link = reverse('admin:%s_%s_change' % info, args=(obj.article.id,))
|
|
|
|
|
return format_html(
|
|
|
|
|
u'<a href="%s">%s</a>' % (link, obj.article.title))
|
|
|
|
|
|
|
|
|
|
link_to_userinfo.short_description = _('User')
|
|
|
|
|
link_to_article.short_description = _('Article')
|
|
|
|
|
'id', # 用户ID
|
|
|
|
|
'nickname', # 用户昵称
|
|
|
|
|
'username',# 用户名
|
|
|
|
|
'email', # 电子邮箱
|
|
|
|
|
'last_login', # 最后登录时间
|
|
|
|
|
'date_joined', # 注册时间
|
|
|
|
|
'source')# 用户来源标记
|
|
|
|
|
|
|
|
|
|
# 设置哪些字段可以点击跳转到编辑页
|
|
|
|
|
list_display_links = ('id', 'username')
|
|
|
|
|
|
|
|
|
|
# 默认排序规则(按ID降序排列)
|
|
|
|
|
ordering = ('-id',)
|
|
|
|
|
|
|
|
|
|
|