Django之权限管理

Django权限管理之初步完整版

项目背景:这是一个权限管理系统(给一些角色和他们的权限指URL和页面可以删除的按钮比如:增删改查)

使用到了中间件,和初始化权限,使用了admin的后台管理系统。

我们这个是基于角色的权限访问控制(Role-Based Access Control)做一个组件。

首先建立一个项目工程里面有另个应用:app01与rbac,

我们在rbac中model中建立一些数据类型代码如下:

from django.db import models

# Create your models her
class  Menu(models.Model):#定义一个菜单组
    """菜单组"""
    title=models.CharField(max_length=32)
class Group(models.Model):#权限组(用户组与权限组)
    """权限组"""
    caption=models.CharField(verbose_name="组名称",max_length=32)#组的名称
    menu=models.ForeignKey(verbose_name="所属菜单",to="Menu",default=1)#
class Permission(models.Model):#权限表
    """权限表"""
    url=models.CharField(max_length=64,verbose_name="URL")#权限表的url
    title=models.CharField(max_length=64,verbose_name="标题")#权限表的名字
    menu_gp=models.ForeignKey(verbose_name="组内菜单",to="Permission",null=True,blank=True)#自关联 ,blank是在admin里可以设置为空,null是设置数据库的字段可以为空。
    code=models.CharField(verbose_name="代码",max_length=16)#定义代码
    group=models.ForeignKey(verbose_name="所属组",to="Group",null=True)#所属组

    class Meta:#在admin里面显示表明
         verbose_name_plural="权限表"
    def  __str__(self):#打印名字
        return  self.title

class Userinfo(models.Model):#用户组
    """用户表"""
    username=models.CharField(verbose_name="名字",max_length=32)#用户的名字
    password=models.CharField(verbose_name="密码",max_length=32)#用户的password
    user_role=models.ManyToManyField(verbose_name="所有的角色",to="Role",blank=True)#和角色进行多对多关联
    class Meta:#在admin里面显示表明
        verbose_name_plural="用户表"
    def __str__(self):
        return  self.username
class Role(models.Model):#角色名字
    """角色表"""
    title=models.CharField(verbose_name="职位",max_length=32)#角色的名字
    role_permission=models.ManyToManyField(verbose_name="权限",to="Permission",blank=True)
    class Meta:
        verbose_name_plural="角色表"
    def __str__(self):
        return  self.title

rbac中的model

再rbac中的admin中填入需要在生成的数据代码如下:

from django.contrib import admin

# Register your models here.
from . import models#用djangoadmin时一定要在这里写东西
admin.site.register(models.Permission)
admin.site.register(models.Userinfo)
admin.site.register(models.Role)

中间件的代码如下:

import re
from django.shortcuts import redirect,HttpResponse
from django.conf import settings
class MiddlewareMixin(object):#这个是中间件
    def __init__(self, get_response=None):
        self.get_response = get_response
        super(MiddlewareMixin, self).__init__()

    def __call__(self, request):
        response = None
        if hasattr(self, ‘process_request‘):
            response = self.process_request(request)
        if not response:
            response = self.get_response(request)
        if hasattr(self, ‘process_response‘):
            response = self.process_response(request, response)
        return response
class Middle(MiddlewareMixin):
    def process_request(self,request):
        #1 .获取当前请求的URL
        # request.path_info
        #2. 获取Session中保存当前用户的权限
        # request.session.get("permission_url_list")
        current_url=request.path_info#这个是获取的当前请求的路径
        print("当前请求的路径",current_url)#获取当前的url
        for url in settings.VALID_URL:#这里设置白名单
            if re.match(url,current_url):#匹配是否在白名单这个不要格式化
                return  None#返回None返回为空就可以经过下一个中间
        permission_dict = request.session[settings.PERMISSION_URL_DICT_KEY]#获取权限url和这个页面的某些权限
        print("有这些权限URl",permission_dict)
        if not permission_dict:
            return   redirect("/login/")#如果没有登录就直接返回登录页面
        flag = False#设置一个flag
        for group_id ,code_url in permission_dict.items():#字典循环获取值用 字典名.items()
            for db_url in code_url["urls"]:#循环取里面的url
                regax="^{0}$".format(db_url)#对取出的url进行格式化
                if re.match(regax,current_url):#通过匹配找出是否在这里面
                    request.permission_code_list=code_url["codes"]
                    print("这里是获取的是单个页面里面的权限",request.permission_code_list)
                    flag=True#如果匹配成功直接跳出去
                    break
            if flag:
                break
        if not flag:#如果没有跳出说明他没有权限
            return  HttpResponse("你没有权限")

中间的代码

初始化权限的代码:

from django.conf import settings
def init__perimission(user,request):#初始化权限
    perimission_list = user.user_role.values("role_permission__id",#权限的id
                                             "role_permission__title",#权限的名字
                                             "role_permission__url",#权限的url
                                             # "role_permission__is_menu",
                                             "role_permission__code",#权限名字的代码
                                             "role_permission__menu_gp_id",#组内菜单的id(一个组的菜单id)
                                             "role_permission__group_id",#所属的组
                                             "role_permission__group__menu_id",#菜单id
                                             "role_permission__group__menu__title",#菜单的名字
                                             ).distinct()#这里获取的是的个人的权限与明细
    print("这就是最终拿到的个人明细",perimission_list)
   # 更改菜单(这个菜单是在同一个组内的菜单不变始终存在)
    sub_perimission_list=[]#先定义一个列表
    for item in perimission_list:#首先是循环里面所有的数据
        tpl={
            "id":item["role_permission__id"],#获取id是权限的id
            "title":item["role_permission__title"],#获取的是权限的名字
            "url":item["role_permission__url"],#权限的url
            "menu_gp_id":item["role_permission__menu_gp_id"],#这是组内菜单的id
            "menu_id":item["role_permission__group__menu_id"],#这是菜单的id
            "menu_title":item["role_permission__group__menu__title"]#这是菜单的名字
        }
        sub_perimission_list.append(tpl)#加入到列表中
    request.session[settings.PERMISSION_MEN_KEY] = sub_perimission_list#复制到session
    "-----------以上是菜单的处理"
    #权限的处理
    result ={}#先定义一个字典
    for item in perimission_list:#从这个数据里循环数据
        group_id=item["role_permission__group_id"]#所属组
        code=item["role_permission__code"]#一个页面里的有哪些的权限
        url=item["role_permission__url"]#权限对应的url
        if group_id in result:
            result[group_id]["codes"].append(code)#加入权限代码
            result[group_id]["urls"].append(url)#加入权限url
        else:
            result[group_id]={
                "codes":[code,],
                "urls":[url,],
            }
    request.session[settings.PERMISSION_URL_DICT_KEY]=result#赋值权限

初始化

数据库的持久化后接着用admin的后台填一些数据:

我们自己设置了关于网页的自定义标签:名字是rbac

import re
from django.template import Library
from django.conf import settings
register = Library()

#自定义的标签
@register.inclusion_tag("xxxx.html")#从别的地方拿到数据
def menu_html(request):
    menu_list = request.session[settings.PERMISSION_MEN_KEY]#拿到菜单的数据
    current_url = request.path_info#当前的url
    menu_dict = {}#定义一个字典
    for item in menu_list:#先拿到所有的菜单
        if not item["menu_gp_id"]:#判断是否是菜单
            menu_dict[item["id"]]=item#如果是就把数据赋值给他
    for item in menu_list:#这个是循环所有的数据进行url的匹配  给要匹配的url匹配出要显示哪个页面
        regex="^{0}$".format(item["url"])#先把数据进行格式化
        if re.match(regex,current_url):#如果匹配到数据
            menu_gp_id=item["menu_gp_id"]#最内菜单id
            if menu_gp_id:#如果是数字就给这个数字加上“active”=True
                menu_dict[menu_gp_id]["active"]=True
            else:
                menu_dict[item["id"]]["active"]=True#如果不是的当前的加上“active”=True
    result={}#先定义一个字典
    for item in menu_dict.values():#这是字典的取值
        active=item.get("active")#获取它的active
        menu_id=item["menu_id"]#获取菜单值
        if menu_id in result:
            result[menu_id]["children"].append({"title":item["title"],"url":item["url"],"active":active})
            if active:
                result[menu_id]["active"]=True#获取菜单的active用来判断是否加上hide
        else:
            result[menu_id]={
                "menu_id":item["menu_id"],
                "menu_title":item["menu_title"],
                "active":active,#判断
                "children":[
                    {
                        "titel":item["title"],
                         "url":item["url"],
                        "active":active   #这个的话是用来判断是否需要标红的
                    }
                ]
            }
    return {‘menu_dict‘:result}#返回用来显示字典的

xxxx代码:

{% for foo,item in menu_dict.items %}
    <div class="item">
        <div class="item-title">{{ item.menu_title }}</div>
        {% if item.active %}
            <div class="item-permission">
        {% else %}
            <div class="item-permission hide">
        {% endif %}
        {% for v in item.children %}
            {% if v.active %}
                <a href="{{ v.url }}" class="active">{{ v.titel }}</a>
            {% else %}
                <a href="{{ v.url }}">{{ v.titel }}</a>
            {% endif %}
            </div>
        {% endfor %}
        </div>
{% endfor %}

这是应用app01里调用代码:名字是layout是模板

{% load rbac %}<!--这个是继承自定义标签的-->
<!--这个是模板以后都从这个继承-->
<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="/static/rbac/rbac.css"><!--这个是导入css样式-->
</head>
<body>

<div class="header">
    {% block header %}
        <h1>欢迎回来</h1>
    {% endblock header %}
</div>
<div class="siderbar">
    {% block siderbar %}
        {% menu_html request %}<!--这个是产生菜单的样式-->
    {% endblock siderbar %}
</div>
<div class="content">
    {% block content %}
    {% endblock content %}
</div>
<script src="/static/jquery-3.2.1.min.js"></script>
<script src="/static/rbac/rabc.js"></script><!--这个是导入js样式-->
</body>
</html>

layout

别的页面也是继承这个页面:

{% extends ‘layout.html‘ %}

{% block content %}
    {% if page_permission.has_add %}
    <a href="/userinfo/add/">添加用户11</a>
             {% endif %}
    <table>
        {% for user in userlist %}
            <tr>
                <td>{{ user.id }}</td>
                <td>{{ user.name }}</td>
                 {% if  page_permission.has_edit %}
                <td><a href="">编辑</a></td>
                     {% endif %}
               {% if  page_permission.has_del %}
                <td><a href="">删除</a></td>
            {% endif %}
            </tr>
        {% endfor %}

    </table>
{% endblock %}

userinfo

在判断一个权限是否属于时可以建立一个类:

class BasePagePermission(object):#有某一个更改的权限
    def __init__(self,code_list):
        self.code_list=code_list
    def has_add(self):
        if "add" in self.code_list:
            return  True
    def has_edit(self):
        if "edit" in self.code_list:
            return  True
    def has_del(self):
        if "del" in self.code_list:
            return  True

建立一个类

项目app01中的view中的代码:

import re
from django.shortcuts import render,redirect,HttpResponse
from rbac import models
from rbac.server.init_permission import init__perimission
def login(request):     #登录判断
    if request.method=="GET":
        return render(request,"login.html")
    else:
        name=request.POST.get("name")
        pwd=request.POST.get("pwd")
        user=models.Userinfo.objects.filter(username=name,password=pwd).first()
        print("用户名",user)
        if not user:
            return render(request,"login.html")
        init__perimission(user,request)#初始化权限
        return  redirect("/index/")#返回权限
def index(request):
    return  render(request,"index.html")
class BasePagePermission(object):#有某一个更改的权限
    def __init__(self,code_list):
        self.code_list=code_list
    def has_add(self):
        if "add" in self.code_list:
            return  True
    def has_edit(self):
        if "edit" in self.code_list:
            return  True
    def has_del(self):
        if "del" in self.code_list:
            return  True
def  userinfo(request):
    pagepermission= BasePagePermission(request.permission_code_list)#查看有哪些表有哪些删除或者修改的权限
    data_list=[
        { "id":1,"name":"xx1" },
        { "id":2,"name":"xx1" },
        { "id":3,"name":"xx1" },
        { "id":4,"name":"xx1" },
        { "id":5,"name":"xx1" }
    ]
    return render(request,"userinfo.html",{"userlist":data_list,"page_permission":pagepermission})#返回的是数据和是不是有这些权限的布尔值

def  userinfoadd(request):
    userinfo_permission = BasePagePermission(request.permission_code_list)
    return render(request,"userinfo_add.html",{"gepermissionon":userinfo_permission})
class OrderPermission(BasePagePermission):
    def  has_order(self):
        if "order" in self.code_list:
           return  True
def userinfodel(request,nid):
    return HttpResponse("删除人员信息")
def userinfoedit(request,nid):
    return  HttpResponse("编辑人员信息")
def orderinfo(request):
    order_permission = BasePagePermission(request.permission_code_list)
    return render(request,"orderinfo.html")
def orderinfoadd(request):
    return  HttpResponse("增加订单")
def orderinfodel(request,nid):
    return HttpResponse("删除订单")
def orderinfoedit(request,nid):
    return  HttpResponse("编辑订单")

app01的代码

用到的js代码:

 $(function () {
    $(‘.item-title‘).click(function () {
        // if($(this).next().hasClass(‘hide‘)){
        //     $(this).next().removeClass(‘hide‘)
        // }else{
        //     $(this).next().addClass(‘hide‘)
        // }
        // alert(111)
        $(this).next().toggleClass(‘hide‘);
    })
});

点击隐藏的代码

中间件的代码结构:

在这次项目中我们要在settings里面配置白名单和两个全局变量。

注:如果把组件导入到另一项目中,一定要在views中login函数中导入组件中的的models。源码放在了78天准备练习中

时间: 2024-11-06 13:40:19

Django之权限管理的相关文章

Django之权限管理插件

参考:https://www.cnblogs.com/alex3714/articles/6661911.html http://www.cnblogs.com/wupeiqi/articles/6229414.html 1.      什么是权限? 权限就是对软件系统中各种资源的访问和操作的控制! 2.      什么是资源? 在软件系统中,数据库.内存.硬盘里数据都是资源,资源就是数据! 3.      动作 资源本身是静态的,必须通过合适的动作对其进行访问和操作,我们说要控制权限,其实本质

django之权限管理公共组件

公共组件使用 公共组件的基本搭建 在上一篇已经是学习如何搭建一个公共组件,可以拷贝到任何项目里面,实现权限的管理工作,今天再次学习下公共组件的使用 新建一个项目,并把公共组件拷贝到新项目中取,并且在setting中注册组件 中间件的注册 公共组件的配置管理 在中间件中,通过导入项目的setting文件,从里面导入变量信息,所以我们在setting里面设置了如下变量信息: # ############################## RBAC权限相关配置开始 #################

django 自定义user使用权限管理模块

这篇文章主要是讲如何让自定义的user模块也能用到django.contrib.auth中的权限管理模块 看这篇文章之前请先看一下我前边的两篇文章,本文以这两篇文章为基础: django 自定义 USER 用源码告诉你django权限管理是怎么回事 下边是一个大概的实现,后边再做详细分析: 1.user model自定义 class AbstractUser(models.Model): # 登录信息 id = models.AutoField(primary_key=True) staff =

2.4、使用Django自带的admin用户管理,权限管理

如何创建项目请参考2.2.创建项目. 通常web服务会要求注册的用户通过用户名和密码登录,然后才可能管理自己的信息或者对一些页面进行授权,判断用户是否拥有执行某种操作的权限. Django已经提供了一个django.contrib.auth应用来处理登录,登出和权限验证,同时还提供了django.contrib.admin应用来管理用户.可以参考你的虚拟python环境的/lib/python27/site-packges/django/contrib/admin里面的文件和源码. 我们要做的就

django 基于proxy实现用户权限管理

项目中经常会遇到用户权限管理的问题,django adminsite已经提供非常实用的用户权限管理机制.不过有些时候,我们希望根据相关用户属性来过滤adminsite中显示的内容.下文将结束如何实现: 原始类 假设我有这么一个问卷类,基于这个类可以实现增删改查的功能 class wenjuan(models.Model): """ 问卷 """ name=models.CharField(u'问卷名称',max_length=128) breif

[Django]用户权限学习系列之设计自有权限管理系统设计思路

若在阅读本片文章遇到权限操作问题,请查看本系列的前两章! http://www.cnblogs.com/CQ-LQJ/p/5609690.html和http://www.cnblogs.com/CQ-LQJ/p/5604331.html 现在步入正题,这篇文章是关于自有权限管理系统设计的思路描述,自有权限管理系统是抛弃django自带的后台管理界面,基于自己编写的权限管理界面对用户权限的管理! 首先上图:(自己设计的权限系统界面,代码将后续文章中写出) 权限管理界面主要是添加和删除权限,查看官方

Django—内置用户权限管理

内置用户权限管理 对于注册.登录.验证等功能我们可以自己编写用户管理应用,但Django也有一个内置的用户权限管理系统.也是很强大的. 在哪可以看到? 关于用户的信息都存放在这个表中. auth模块 from django.contrib import auth 其中有几个常用的方法: authenticate() 提供了用户认证功能,即验证用户名以及密码是否正确,一般需要username .password两个关键字参数. 如果认证成功(用户名和密码正确有效),便会返回一个 User 实例对象

基于Django实现RBAC权限管理

概述 RBAC(Role-Based Access Control,基于角色的访问控制),通过角色绑定权限,然后给用户划分角色.在web应用中,可以将权限理解为url,一个权限对应一个url. 在实际应用中,url是依附在菜单下的,比如一个简单的生产企业管理系统,菜单可以大致分为以下几块:制造.资材.生产管理.人事.财务等等.每个菜单下又可以有子菜单,但最终都会指向一个url,点击这个url,通过Django路由系统执行一个视图函数,来完成某种操作.这里,制造部的员工登录系统后,肯定不能点击财务

djiango -权限管理

一.权限管理表结构 model.py from django.db import models # Create your models here. #权限表 class Permission(models.Model): # caption = models.CharField(max_length=32) parent_id = models.ForeignKey('Permission', related_name='k', to_field='id', null=True, blank=