rbac权限管理系统

models.py (数据表,一个8张表)

from django.db import models

# Create your models here.


class User(models.Model):
    '''
    用户表
    '''
    user = models.CharField(max_length=32,verbose_name='用户名',unique=True)
    caption = models.CharField(max_length=32,verbose_name='姓名')
    passwd = models.CharField(max_length=32,verbose_name='密码')

    class Meta:
        verbose_name_plural = '用户表'
        db_table = 'rbac_user'

    def __str__(self):
        return self.caption

class Role(models.Model):
    '''
    角色表
    '''
    caption = models.CharField(max_length=32,verbose_name='角色名',unique=True)

    class Meta:
        verbose_name_plural = '角色'
        db_table = 'rbac_role'

    def __str__(self):
        return self.caption

class User2Role(models.Model):
    '''
    用户角色关系表
    '''
    user = models.ForeignKey('User',on_delete=models.CASCADE,verbose_name='用户名')
    role = models.ForeignKey('Role',on_delete=models.CASCADE,verbose_name='所属角色')

    class Meta:
        verbose_name_plural = '用户角色关系表'
        unique_together = ('user','role')
        db_table = 'rbac_user2role'

    def __str__(self):
        return '%s==>%s' % (self.user.caption,self.role.caption)

class UrlPermission(models.Model):
    '''
    url权限表
    '''
    url = models.CharField(max_length=50,verbose_name='url地址',unique=True)
    caption = models.CharField(max_length=32,verbose_name='所属模块')
    menu = models.ForeignKey('Menu',on_delete=models.CASCADE,null=True,blank=True)

    class Meta:
        verbose_name_plural = 'url权限表'
        db_table = 'rbac_urlpermission'

    def __str__(self):
        return '%s == >%s' %(self.caption,self.url)

class Menu(models.Model):
    '''
    菜单表
    '''
    caption = models.CharField(max_length=50,verbose_name='菜单名')
    parent = models.ForeignKey('Menu',on_delete=models.CASCADE,null=True,blank=True)

    class Meta:
        verbose_name_plural = '菜单表'
        unique_together = ('caption','parent')
        db_table = 'rbac_menu'

    def __str__(self):
        return self.caption

class Action(models.Model):
    code = models.CharField(max_length=32,verbose_name='功能代码',unique=True)
    caption = models.CharField(max_length=32,verbose_name='功能名')

    class Meta:
        verbose_name_plural = '功能表'
        db_table = 'rbac_action'

    def __str__(self):
        return '%s:%s' %(self.caption,self.code)

class UrlPermission2Action(models.Model):
    urlpermission = models.ForeignKey('UrlPermission',on_delete=models.CASCADE,verbose_name='url地址')
    action = models.ForeignKey('Action',on_delete=models.CASCADE,verbose_name='拥有功能')

    class Meta:
        verbose_name_plural = 'url权限功能关系表'
        unique_together = ('urlpermission','action')
        db_table = 'rbac_urlpermission2action'

    def __str__(self):
        return '%s?type=%s' %(self.urlpermission.url,self.action.code)

class Role2Url2Action(models.Model):
    role = models.ForeignKey('Role',on_delete=models.CASCADE,verbose_name='角色')
    url2action = models.ForeignKey('UrlPermission2Action',on_delete=models.CASCADE,verbose_name='拥有权限')

    class Meta:
        verbose_name_plural = '角色权限关系表'
        unique_together = ('role','url2action')
        db_table = 'rbac_role2url2action'

    def __str__(self):
        return '%s===>%s:%s   %s' %(self.role.caption,self.url2action.urlpermission.caption,\
                                    self.url2action.action.caption,self.url2action)

permission.py 有关权限类与装饰器

from django.shortcuts import redirect,HttpResponse
from rbac import  models
import re


def permisson(func):

    def inner(request,*args,**kwargs):
        if not request.session.get('user_info'):
            return redirect('/login.html')
        user = request.session['user_info']['user']
        obj = PermissionManager(request,user)
        kwargs['action_list'] = obj.action()
        if not kwargs['action_list']:
            return HttpResponse('你无权访问')
        kwargs['menu_list'] = obj.menu_tree(obj.get_menudata())
        return func(request,*args,**kwargs)
    return inner

class PermissionManager:
    def __init__(self,request,user):
        self.request = request
        # self.current_page = '/user.html'
        self.current_page = request.path_info

        self.user = user
        self.menu_list = {}
        self.menu_leaf_list = {}
        self.urlpermission_list = {}
        self.menu_leaf_parent = None
        self.session_data()

    def session_data(self):
        pageinfo = self.request.session.get('pageinfo')
        if pageinfo:
            self.menu_leaf_list = pageinfo['menu_leaf_list']
            self.urlpermission_list = pageinfo['urlpermission_list']
            self.menu_list = pageinfo['menu_list']
        else:
            #获取所有url权限,并且保存为这种格式
            #  {'/index.html': ['get'], '/user.html': ['add', 'delete', 'get', 'update']}
            urlpermission = models.Role2Url2Action.objects.filter(role__user2role__user__user=self.user).\
                values('url2action__urlpermission__url','url2action__action__code').\
                order_by('url2action__urlpermission__url','url2action__action__code').distinct()
            for i in urlpermission:
                if i['url2action__urlpermission__url'] in self.urlpermission_list:
                    self.urlpermission_list[i['url2action__urlpermission__url']].append(i['url2action__action__code'])
                else:
                    self.urlpermission_list[i['url2action__urlpermission__url']] = [i['url2action__action__code'],]

            #获取叶子菜单,带有url的菜单,并且将数据格式化
            menu_leaf = list(models.Role2Url2Action.objects.filter(role__user2role__user__user=self.user).\
                values('url2action__urlpermission__menu_id','url2action__urlpermission__url','url2action__urlpermission__caption').\
                order_by('url2action__urlpermission__menu_id','url2action__urlpermission__url','url2action__urlpermission__caption').distinct())

            menu_list = list(models.Menu.objects.values('id', 'caption', 'parent_id'))

            self.request.session['pageinfo'] = {
                'menu_list' : menu_list,
                'menu_leaf_list' : menu_leaf,
                'urlpermission_list' : self.urlpermission_list
            }

            self.menu_leaf_list = menu_leaf
            self.menu_list = menu_list

    def get_menudata(self):

        menu_leaf_list = {}

        for i in self.menu_leaf_list:
            menu = {
                'parent_id': i['url2action__urlpermission__menu_id'],
                'caption': i['url2action__urlpermission__caption'],
                'url': i['url2action__urlpermission__url'],
                'status': True,
                'open': False
            }

            if re.match(menu['url'], self.current_page):
                menu['open'] = True
                self.menu_leaf_parent = menu['parent_id']
            if menu['parent_id'] in menu_leaf_list:
                menu_leaf_list[menu['parent_id']].append(menu)
            else:
                menu_leaf_list[menu['parent_id']] = [menu, ]

                # 获取所有菜单节点
        menu_list = {}
        for i in self.menu_list:
            menu = {
                'id': i['id'],
                'caption': i['caption'],
                'parent_id': i['parent_id'],
                'child': [],
                'status': False,
                'open': False
            }
            menu_list[menu['id']] = menu

        for k,v in menu_leaf_list.items():
            parent = k
            menu_list[parent]['child'] = v
            while parent:
                menu_list[parent]['status'] = True
                parent = menu_list[parent]['parent_id']

        while self.menu_leaf_parent:
            menu_list[self.menu_leaf_parent]['open'] = True
            self.menu_leaf_parent = menu_list[self.menu_leaf_parent]['parent_id']

        result = []

        for i in menu_list.values():
            if i['parent_id']:
                menu_list[i['parent_id']]['child'].append(i)
            else:
                result.append(i)

        return result

    def menu_tree(self,data):

        resphone = ''
        div = """
            <div>
                <div class='title'>%s</div>
                <div class='content %s'>%s</div>
            </div>
        """
        for i in data:
            active = ''
            if i['open']:
                active = 'active'
            if i['status']:
                if 'url' in i:
                    url = i['url']
                    title = i['caption']
                    content = '<a href="%s" class="%s"> %s </a>'
                    resphone += content % (url,active,title)
                else:

                    title = i['caption']
                    content = self.menu_tree(i['child'])
                    resphone += div %(title,active,content)
        return resphone

    def action(self):
        action_list = []
        for k,v in self.urlpermission_list.items():
            if re.match(k,self.current_page):
                action_list = v
                break
        return action_list

views.py

from django.shortcuts import render,HttpResponse,redirect
from rbac import  permission
# Create your views here.
from rbac import models

@permission.permisson
def index(request,*args,**kwargs):

    return render(request,'index.html',{'menu':kwargs['menu_list'],'action_list':kwargs['action_list']})


def login(request):
    if request.method == "GET":
        if request.session.get('user_info'):
            return redirect('/index.html')
        return render(request,'login.html')
    else:
        user = request.POST.get('user')
        passwd = request.POST.get('passwd')
        c = models.User.objects.filter(user=user,passwd=passwd).count()
        if c:
            request.session['user_info'] = {
                'user':user
            }
            return redirect('/index.html')
        else:
            return redirect('/login.html')
def logout(request):
    request.session.clear()
    return  redirect('/login.html')

urls.py

"""权限管理 URL Configuration

The `urlpatterns` list routes URLs to views. For more information please see:
    https://docs.djangoproject.com/en/2.2/topics/http/urls/
Examples:
Function views
    1. Add an import:  from my_app import views
    2. Add a URL to urlpatterns:  path('', views.home, name='home')
Class-based views
    1. Add an import:  from other_app.views import Home
    2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
Including another URLconf
    1. Import the include() function: from django.urls import include, path
    2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
"""
from django.contrib import admin
from django.urls import path,re_path
from rbac import  views

urlpatterns = [
    path('admin/', admin.site.urls),
    re_path('^login.html$',views.login),
    re_path('^index.html$',views.index),
    path('logout/',views.logout)
]

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/login.html" method="post">{% csrf_token %}
    <input type="text" name="user">
    <input type="text" name="passwd">
    <input type="submit">
</form>
</body>
</html>

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        .content {
            margin-left: 20px;
            display: none;
        }
        .active {
            display: block;
        }
    </style>
</head>
<body>
    <div>
        {{ menu|safe }}
    </div>
    <div>
        {{ action_list }}
    </div>
</body>
</html>

admin.py

from django.contrib import admin
from rbac import models
# Register your models here.

admin.site.register(models.User)
admin.site.register(models.Role)
admin.site.register(models.User2Role)
admin.site.register(models.UrlPermission)
admin.site.register(models.Menu)
admin.site.register(models.Action)
admin.site.register(models.UrlPermission2Action)
admin.site.register(models.Role2Url2Action)

 

posted @ 2019-12-09 16:03  Mr-谢  阅读(237)  评论(0)    收藏  举报