重写AuditUserFieldsMixin

This commit is contained in:
xie7654
2025-06-30 22:26:00 +08:00
parent c7f7bf9258
commit 05554eb821
6 changed files with 30 additions and 29 deletions

View File

@@ -6,6 +6,7 @@ from rest_framework.response import Response
from system.models import Menu, MenuMeta from system.models import Menu, MenuMeta
from utils.custom_model_viewSet import CustomModelViewSet from utils.custom_model_viewSet import CustomModelViewSet
from utils.serializers import CustomModelSerializer
class MenuMetaSerializer(serializers.ModelSerializer): class MenuMetaSerializer(serializers.ModelSerializer):
@@ -14,7 +15,7 @@ class MenuMetaSerializer(serializers.ModelSerializer):
model = MenuMeta model = MenuMeta
fields = '__all__' fields = '__all__'
class MenuSerializer(serializers.ModelSerializer): class MenuSerializer(CustomModelSerializer):
"""菜单序列化器""" """菜单序列化器"""
parent = serializers.CharField(source='pid.name', read_only=True) parent = serializers.CharField(source='pid.name', read_only=True)
meta = MenuMetaSerializer() meta = MenuMetaSerializer()
@@ -46,11 +47,13 @@ class MenuSerializer(serializers.ModelSerializer):
"""创建菜单及关联的元数据""" """创建菜单及关联的元数据"""
meta_data = validated_data.pop('meta') meta_data = validated_data.pop('meta')
meta = MenuMeta.objects.create(**meta_data) meta = MenuMeta.objects.create(**meta_data)
self.set_audit_user_fields(validated_data, is_create=True)
menu = Menu.objects.create(meta=meta, **validated_data) menu = Menu.objects.create(meta=meta, **validated_data)
return menu return menu
def update(self, instance, validated_data): def update(self, instance, validated_data):
"""更新菜单及关联的元数据""" """更新菜单及关联的元数据"""
self.set_audit_user_fields(validated_data, is_create=False)
meta_data = validated_data.pop('meta', {}) meta_data = validated_data.pop('meta', {})
meta_serializer = self.fields['meta'] meta_serializer = self.fields['meta']
meta_serializer.update(instance.meta, meta_data) meta_serializer.update(instance.meta, meta_data)

View File

@@ -7,9 +7,10 @@ from rest_framework.response import Response
from system.models import RolePermission, Menu, Role from system.models import RolePermission, Menu, Role
from utils.custom_model_viewSet import CustomModelViewSet from utils.custom_model_viewSet import CustomModelViewSet
from utils.serializers import CustomModelSerializer
class RoleSerializer(serializers.ModelSerializer): class RoleSerializer(CustomModelSerializer):
"""角色序列化器""" """角色序列化器"""
permissions = serializers.PrimaryKeyRelatedField( permissions = serializers.PrimaryKeyRelatedField(
queryset=Menu.objects.all(), queryset=Menu.objects.all(),
@@ -34,7 +35,7 @@ class RoleViewSet(CustomModelViewSet):
queryset = Role.objects.all() queryset = Role.objects.all()
serializer_class = RoleSerializer serializer_class = RoleSerializer
filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter] filter_backends = [DjangoFilterBackend, SearchFilter, OrderingFilter]
filterset_fields = ['status'] filterset_fields = ['status', 'name']
search_fields = ['name'] search_fields = ['name']
ordering_fields = ['create_time'] ordering_fields = ['create_time']

View File

@@ -9,15 +9,29 @@ from django.utils.functional import cached_property
from rest_framework.utils.serializer_helpers import BindingDict from rest_framework.utils.serializer_helpers import BindingDict
class CustomModelSerializer(ModelSerializer): class AuditUserFieldsMixin:
""" """
增强DRF的ModelSerializer,可自动更新模型的审计字段记录 用于自动赋值 creator 和 modifier 字段的 Mixin
(1)self.request能获取到rest_framework.request.Request对象
""" """
# 修改人的审计字段名称, 默认modifier, 继承使用时可自定义覆盖 # 修改人的审计字段名称, 默认modifier, 继承使用时可自定义覆盖
modifier_field_id = 'modifier' modifier_field_id = 'modifier'
# 创建人的审计字段名称, 默认creator, 继承使用时可自定义覆盖 # 创建人的审计字段名称, 默认creator, 继承使用时可自定义覆盖
creator_field_id = 'creator' creator_field_id = 'creator'
def set_audit_user_fields(self, validated_data, is_create=True):
username = self.get_request_username() if hasattr(self, 'get_request_username') else None
if getattr(self, 'request', None):
if self.modifier_field_id in self.fields:
validated_data[self.modifier_field_id] = username
if is_create and self.creator_field_id in self.fields:
validated_data[self.creator_field_id] = username
class CustomModelSerializer(AuditUserFieldsMixin, ModelSerializer):
"""
增强DRF的ModelSerializer,可自动更新模型的审计字段记录
(1)self.request能获取到rest_framework.request.Request对象
"""
# 添加默认时间返回格式 # 添加默认时间返回格式
create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True) create_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False, read_only=True)
update_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False) update_time = serializers.DateTimeField(format="%Y-%m-%d %H:%M:%S", required=False)
@@ -30,17 +44,11 @@ class CustomModelSerializer(ModelSerializer):
return super().save(**kwargs) return super().save(**kwargs)
def create(self, validated_data): def create(self, validated_data):
if self.request: self.set_audit_user_fields(validated_data, is_create=True)
if self.modifier_field_id in self.fields:
validated_data[self.modifier_field_id] = self.get_request_username()
if self.creator_field_id in self.fields:
validated_data[self.creator_field_id] = self.get_request_username()
return super().create(validated_data) return super().create(validated_data)
def update(self, instance, validated_data): def update(self, instance, validated_data):
if self.request: self.set_audit_user_fields(validated_data, is_create=False)
if hasattr(self.instance, self.modifier_field_id):
validated_data[self.modifier_field_id] = self.get_request_username()
return super().update(instance, validated_data) return super().update(instance, validated_data)
def get_request_username(self): def get_request_username(self):

View File

@@ -7,8 +7,10 @@ export namespace SystemRoleApi {
[key: string]: any; [key: string]: any;
id: string; id: string;
name: string; name: string;
permissions: [];
profile: { profile: {
create_time: string; create_time: string;
permissions: [];
remark?: string; remark?: string;
status: 0 | 1; status: 0 | 1;
}; };

View File

@@ -49,7 +49,6 @@ export function useGridFormSchema(): VbenFormSchema[] {
fieldName: 'name', fieldName: 'name',
label: $t('system.role.roleName'), label: $t('system.role.roleName'),
}, },
{ component: 'Input', fieldName: 'id', label: $t('system.role.id') },
{ {
component: 'Select', component: 'Select',
componentProps: { componentProps: {
@@ -62,16 +61,6 @@ export function useGridFormSchema(): VbenFormSchema[] {
fieldName: 'status', fieldName: 'status',
label: $t('system.role.status'), label: $t('system.role.status'),
}, },
{
component: 'Input',
fieldName: 'remark',
label: $t('system.role.remark'),
},
{
component: 'RangePicker',
fieldName: 'createTime',
label: $t('system.role.createTime'),
},
]; ];
} }

View File

@@ -58,7 +58,6 @@ const [Drawer, drawerApi] = useVbenDrawer({
} else { } else {
id.value = undefined; id.value = undefined;
} }
if (permissions.value.length === 0) { if (permissions.value.length === 0) {
loadPermissions(); loadPermissions();
} }
@@ -70,8 +69,7 @@ async function loadPermissions() {
loadingPermissions.value = true; loadingPermissions.value = true;
try { try {
const res = await getMenuList(); const res = await getMenuList();
console.log(res, 'res') permissions.value = res as unknown as DataNode[];
permissions.value = res.items as unknown as DataNode[];
} finally { } finally {
loadingPermissions.value = false; loadingPermissions.value = false;
} }
@@ -99,7 +97,7 @@ function getNodeClass(node: Recordable<any>) {
<Drawer :title="getDrawerTitle"> <Drawer :title="getDrawerTitle">
<Form> <Form>
<template #permissions="slotProps"> <template #permissions="slotProps">
<Spin :spinning="loadingPermissions" wrapper-class-name="w-full"> <Spin v-if="permissions.length" :spinning="loadingPermissions" wrapper-class-name="w-full">
<VbenTree <VbenTree
:tree-data="permissions" :tree-data="permissions"
multiple multiple