# -*- coding: utf-8 -*- """ @Remark: 菜单模块 """ from rest_framework import serializers from mysystem.models import Menu, MenuButton, Button from mysystem.views.menu_button import MenuButtonSerializer from utils.jsonResponse import SuccessResponse from utils.serializers import CustomModelSerializer from utils.viewset import CustomModelViewSet from django.db.models import Q from rest_framework.decorators import action from rest_framework.permissions import IsAuthenticated class MenuSerializer(CustomModelSerializer): """ 菜单表的简单序列化器 """ menuPermission = serializers.SerializerMethodField(read_only=True) def get_menuPermission(self, instance): queryset = MenuButton.objects.filter(menu=instance.id).order_by('-name').values_list('name', flat=True) if queryset: return queryset else: return None class Meta: model = Menu fields = "__all__" # exclude = ('description', 'creator', 'modifier') read_only_fields = ["id"] class MenuCreateSerializer(CustomModelSerializer): """ 菜单表的创建序列化器 """ name = serializers.CharField(required=False) class Meta: model = Menu fields = "__all__" #exclude = ('description', 'creator', 'modifier') read_only_fields = ["id"] class MenuTreeSerializer(CustomModelSerializer): """ 菜单表的树形序列化器 """ children = serializers.SerializerMethodField(read_only=True) menuPermission_name = serializers.SerializerMethodField(read_only=True) menuPermission = MenuButtonSerializer(read_only=True,many=True) def get_children(self, instance): queryset = Menu.objects.filter(parent=instance.id).filter(status=1) if queryset: serializer = MenuTreeSerializer(queryset, many=True) return serializer.data else: return None def get_menuPermission_name(self, instance): return list(instance.menuPermission.values_list('name', flat=True)) class Meta: model = Menu fields = "__all__" read_only_fields = ["id"] class WebRouterSerializer(CustomModelSerializer): """ 前端菜单路由的简单序列化器 """ path = serializers.CharField(source="web_path") title = serializers.CharField(source="name") menuPermission = serializers.SerializerMethodField(read_only=True) def get_menuPermission(self, instance): # 判断是否是超级管理员 if self.request.user.is_superuser: return instance.menuPermission.values_list('value', flat=True) else: # 根据当前角色获取权限按钮id集合 permissionIds = list(self.request.user.role.values_list('permission', flat=True)) #获取当前菜单的按钮权限vlaue queryset = instance.menuPermission.filter(id__in=permissionIds, menu=instance.id).values_list('value', flat=True) if queryset: return queryset else: return None class Meta: model = Menu # fields = "__all__" fields = ('id', 'parent', 'icon', 'sort', 'name', 'isautopm', 'web_path', 'visible', 'status','path','title','menuPermission') read_only_fields = ["id"] class WebRouterSerializer2(CustomModelSerializer): """ 前端菜单路由的简单序列化器 """ path = serializers.CharField(source="web_path") title = serializers.CharField(source="name") class Meta: model = Menu # fields = "__all__" fields = ('id', 'parent', 'icon', 'sort', 'name', 'isautopm', 'web_path', 'visible', 'status','path','title','menuPermission') read_only_fields = ["id"] class MenuViewSet(CustomModelViewSet): """ 菜单管理接口 list:查询 create:新增 update:修改 retrieve:单例 destroy:删除 """ queryset = Menu.objects.all().order_by('sort') serializer_class = MenuSerializer create_serializer_class = MenuCreateSerializer update_serializer_class = MenuCreateSerializer filterset_fields = ['name', 'status','visible'] search_fields = ['name','web_path'] def menu_tree(self, request): """用于菜单添加修改中获取父级菜单""" queryset = Menu.objects.filter(parent=None) serializer = MenuTreeSerializer(queryset, many=True) return SuccessResponse(data=serializer.data, msg="获取成功") @action(methods=['get'],extra_filter_backends=[],detail=False)#会自动生成/api/system/menu/web_router/的路由 def web_router(self, request): """用于前端获取当前角色的路由""" user = request.user data = [] if user.is_superuser: queryset = self.filter_queryset(self.queryset).filter(status=1).filter((Q(parent__isnull = True))|(Q(parent__isnull = False)&Q(parent__status = 1))).prefetch_related('menuPermission') # 使用prefetch_related反向一次性加载菜单按钮(优化查询性能,使反向外键在一次查询中加载) menu_button_data = MenuButton.objects.all().values('id','value') serializer = WebRouterSerializer2(queryset, many=True, request=request) data = serializer.data for d in data: menuPermission = [] for m in d['menuPermission']: for mb in menu_button_data: if m == mb['id']: menuPermission.append(mb['value']) break d['menuPermission'] = menuPermission else: menuIds = user.role.values_list('menu__id', flat=True) queryset = self.filter_queryset(Menu.objects.filter(id__in=menuIds, status=1)).filter(Q(parent__isnull = True)|(Q(parent__isnull = False)&Q(parent__status = 1))).prefetch_related('menuPermission') #根据当前角色获取权限按钮id和value数据 menu_button_data = user.role.values('permission__id','permission__value','permission__menu_id') serializer = WebRouterSerializer2(queryset, many=True, request=request) data = serializer.data for d in data: menuPermission = [] for mb in menu_button_data: if mb['permission__menu_id'] == d['id']: menuPermission.append(mb['permission__value']) d['menuPermission'] = menuPermission return SuccessResponse(data=data,total=len(data), msg="获取成功")