from django.db.models import Q from rest_framework import status from rest_framework.decorators import action from rest_framework.permissions import IsAuthenticated from rest_framework.response import Response from rest_framework.viewsets import ModelViewSet from erp_system.tasks import create_menus_permissions from erp_system.models import Menu, PermissionsModel from erp_system.serializers.menus_serializer import MenuSerializer class MenuViewSet(ModelViewSet): """ create: 功能菜单--新增 功能菜单新增, status: 201(成功), return: 新增功能菜单信息 destroy: 功能菜单--删除 功能菜单删除, status: 204(成功), return: None update: 功能菜单--修改,全局修改 功能菜单修改, status: 200(成功), return: 修改后的功能菜单信息 partial_update: 功能菜单--局部修改 功能菜单批修改 status: 200(成功), return: 修改后的功能菜单信息 list: 功能菜单--获取列表 功能菜单列表信息, status: 200(成功), return: 功能菜单信息列表 retrieve: 查询某一个功能菜单 查询指定ID的功能菜单, status: 200(成功), return: 用户功能菜单 find_parent: 查询所有的顶级功能菜单, 不需要传参。 get_menus_by_permission: 查询当前登录的用户,所有的,拥有GET权限的菜单列表,而且这些菜单列表必须是树形结构 返回树形菜单列表, status: 200(成功) """ serializer_class = MenuSerializer queryset = Menu.objects.all() # 必须是登录成功之后才能访问所有功能菜单的接口 # permission_classes = [IsAuthenticated] @action(methods=['get'], detail=False) def find_parent(self, request, *args, **kwargs): lst = self.get_queryset().filter(parent__isnull=True) ser = self.get_serializer(instance=lst, many=True) return Response(ser.data) def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) menu = serializer.save() # 发布异步的任务 if menu and menu.id: create_menus_permissions.delay(menu.id) headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) @action(methods=['get'], detail=False) def get_menus_by_permission(self, request, *args, **kwargs): # 得到当前登录用户 user = request.user # 查询该用户所拥有的权限ID列表 permission_id = user.roles.values_list('permissions', flat=True).distinct() # 过滤那些GET的,或者是顶级菜单权限 menu_ids = PermissionsModel.objects.filter(Q(method='GET') | Q(is_menu=True)).filter(id__in=permission_id)\ .values_list('menu', flat=True) # 根据menu_id得到菜单接口对象 menu_list = Menu.objects.filter(id__in=menu_ids, delete_flag=0).all() serializer = MenuSerializer(instance=menu_list, many=True) # 定义 Element tree_dict = {} # 代表一个父菜单 tree_data = [] try: for item in serializer.data: tree_dict[item['id']] = item for i in tree_dict: if tree_dict[i]['parent']: pid = tree_dict[i]['parent'] parent = tree_dict[pid] parent.setdefault('children', []).append(tree_dict[i]) else: tree_data.append(tree_dict[i]) results = tree_data except KeyError: results = serializer.data return Response(results)