关于rbac:

    (1) 创建表关系:
        class User(models.Model):
            name=models.CharField(max_length=32)
            pwd=models.CharField(max_length=32)
            roles=models.ManyToManyField(to="Role")

            def __str__(self): return self.name

        class Role(models.Model):
            title=models.CharField(max_length=32)
            permissions=models.ManyToManyField(to="Permission")

            def __str__(self): return self.title

        class Permission(models.Model):
            title=models.CharField(max_length=32)
            url=models.CharField(max_length=32)

            def __str__(self):return self.title
    
    (2) 基于admin录入数据


    (3) 登录校验:
        
        if 登录成功:
           
            查询当前登录用户的权限列表注册到session中

    (4) 校验权限(中间件的应用)
        class ValidPermission(MiddlewareMixin):

            def process_request(self,request):

                # 当前访问路径
                current_path = request.path_info

                # 检查是否属于白名单
                valid_url_list=["/login/","/reg/","/admin/.*"]

                for valid_url in valid_url_list:
                    ret=re.match(valid_url,current_path)
                    if ret:
                        return None


                # 校验是否登录

                user_id=request.session.get("user_id")

                if not user_id:
                    return redirect("/login/")


                # 校验权限
                permission_list = request.session.get("permission_list",[])  # ['/users/', '/users/add', '/users/delete/(\\d+)', 'users/edit/(\\d+)']


                flag = False
                for permission in permission_list:

                    permission = "^%s$" % permission

                    ret = re.match(permission, current_path)
                    if ret:
                        flag = True
                        break
                if not flag:
                    return HttpResponse("没有访问权限!")

                return None

 

1.rbac应用下

 

models.py

from django.db import models

# Create your models here.




class User(models.Model):
    name=models.CharField(max_length=32)
    pwd=models.CharField(max_length=32)
    roles=models.ManyToManyField(to="Role")

    def __str__(self): return self.name

class Role(models.Model):
    title=models.CharField(max_length=32)
    permissions=models.ManyToManyField(to="Permission")

    def __str__(self): return self.title

class Permission(models.Model):
    title=models.CharField(max_length=32)
    url=models.CharField(max_length=32)

    action=models.CharField(max_length=32,default="")
    group=models.ForeignKey("PermissionGroup",default=1)
    def __str__(self):return self.title



class PermissionGroup(models.Model):
    title = models.CharField(max_length=32)

    def __str__(self): return self.title

 

 

 admin.py

from django.contrib import admin

# Register your models here.


from .models import *


class PerConfig(admin.ModelAdmin):
    list_display = ["title","url","group","action"]
admin.site.register(User)
admin.site.register(Role)
admin.site.register(Permission,PerConfig)
admin.site.register(PermissionGroup)

 

 

 中间件文件

perssions.py

# by luffycity.com


def initial_session(user,request):
    #方案1
    permissions = user.roles.all().values("permissions__url").distinct()
    # 【{},{}】
    permission_list = []

    for item in permissions:
        permission_list.append(item["permissions__url"])
    print(permission_list)

    request.session["permission_list"] = permission_list

    # 方案2

    # permissions = user.roles.all().values("permissions__url","permissions__group_id","permissions__action").distinct()
    # print("permissions",permissions)
    #
    #
    # permission_dict={}
    # for item in permissions:
    #     gid=item.get('permissions__group_id')
    #
    #     if not gid in permission_dict:
    #
    #         permission_dict[gid]={
    #             "urls":[item["permissions__url"],],
    #             "actions":[item["permissions__action"],]
    #         }
    #     else:
    #         permission_dict[gid]["urls"].append(item["permissions__url"])
    #         permission_dict[gid]["actions"].append(item["permissions__action"])
    #
    #
    # print(permission_dict)
    # request.session['permission_dict']=permission_dict

 

 rbac.py

# by luffycity.com
import re
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import  HttpResponse,redirect


def reg(request,current_path):
    # 校验权限1(permission_list)
    permission_list = request.session.get("permission_list", [])
    flag = False
    for permission in permission_list:

        permission = "^%s$" % permission

        ret = re.match(permission, current_path)
        if ret:
            flag = True
            break
    return flag

class ValidPermission(MiddlewareMixin):

    def process_request(self,request):


        # 当前访问路径
        current_path = request.path_info

        # 检查是否属于白名单
        valid_url_list=["/login/","/reg/","/admin/.*"]

        for valid_url in valid_url_list:
            ret=re.match(valid_url,current_path)
            if ret:
                return None


        # 校验是否登录

        user_id=request.session.get("user_id")

        if not user_id:
            return redirect("/login/")


        #校验权限1(permission_list)
        permission_list = request.session.get("permission_list",[])  # ['/users/', '/users/add', '/users/delete/(\\d+)', 'users/edit/(\\d+)']
        flag=reg(request,current_path)

        if not flag:
            return HttpResponse("没有访问权限!")

        return None

        # 校验权限2

        # permission_dict=request.session.get("permission_dict")
        #
        # for item in permission_dict.values():
        #       urls=item['urls']
        #       for reg in urls:
        #           reg="^%s$"%reg
        #           ret=re.match(reg,current_path)
        #           if ret:
        #               print("actions",item['actions'])
        #               request.actions=item['actions']
        #               return None
        #
        # return HttpResponse("没有访问权限!")

 

 

 2.其他应用app01

views.py

from django.shortcuts import render,HttpResponse

# Create your views here.



from rbac.models import *


class Per(object):
    def __init__(self,actions):
        self.actions=actions
    def add(self):
        return "add" in self.actions
    def delete(self):
        return "delete" in self.actions
    def edit(self):
        return "edit" in self.actions
    def list(self):
        return "list" in self.actions




def users(request):



    user_list=User.objects.all()

    # permission_list=request.session.get("permission_list")
    #print(permission_list)

    # 查询当前登录人得名字

    id=request.session.get("user_id")
    user=User.objects.filter(id=id).first()

    # per=Per(request.actions)

    return render(request,"users.html",locals())











import re
def add_user(request):


    return HttpResponse("add user.....")

def del_user(request,id):

    return HttpResponse("del"+id)


def roles(request):

    role_list=Role.objects.all()
    per = Per(request.actions)
    return render(request,"roles.html",locals())




from rbac.service.perssions import *

def login(request):

    if  request.method=="POST":

        user=request.POST.get("user")
        pwd=request.POST.get("pwd")

        user=User.objects.filter(name=user,pwd=pwd).first()
        if user:
            ############################### 在session中注册用户ID######################
            request.session["user_id"]=user.pk

            ###############################在session注册权限列表##############################



            # 查询当前登录用户的所有角色
            # ret=user.roles.all()
            # print(ret)# <QuerySet [<Role: 保洁>, <Role: 销售>]>

            # 查询当前登录用户的所有权限,注册到session中
            initial_session(user,request)


            return HttpResponse("登录成功!")


    return render(request,"login.html")

 

 

 

3.项目templates模板文件

base.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    <style>
        .header{
            width: 100%;
            height: 60px;
            background-color: #336699;
        }

        .menu{
            background-color: bisque;
            position: fixed;
            top: 60px;
            bottom: 0px;
            left: 0px;
            width: 200px;
        }

        .content{
            position: fixed;
            top: 60px;
            bottom: 0;
            right: 0;
            left: 200px;
            overflow: auto;
            padding: 30px;

        }
    </style>
</head>
<body>


<div class="header">
    <p>{{ user.name }}</p>
</div>
<div class="contain">

        <div class="menu">11</div>
        <div class="content">
        {% block con %}



        {% endblock %}

        </div>

</div>



</body>
</html>

 

login.html

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
</head>
<body>

<h4>登录页面</h4>

<form action="" method="post">
    {% csrf_token %}
    
    用户名:<input type="text" name="user">
    密码:<input type="password" name="pwd">
    <input type="submit">
</form>


</body>
</html>

 

 

 roles.html

{% extends 'base.html' %}

{% block con %}

    <h4>角色列表</h4>


    {% if per.add %}
        <a href="" class="btn btn-primary">添加角色</a>
    {% endif %}

    <table class="table table-bordered table-striped">

       <tbody>
            {% for role in role_list %}
            <tr>
                 <td>{{ forloop.counter }}</td>
                 <td>{{ role.title }}</td>

                 <td>
                     <a href="/users/delete/{{ user.pk }}" class="btn btn-danger">删除</a>
                     <a href="" class="btn btn-warning">编辑</a>

                 </td>
            </tr>
            {% endfor %}

       </tbody>
    </table>



{% endblock %}

 

 users.html

 

{% extends 'base.html' %}


{% block con %}
    {% load my_tags %}
    {% valid '<a href="/users/add/" class="btn btn-primary">添加用户</a>' request %}
    <h4>用户列表</h4>

    {% if per.add %}
    <a href="users/add/" class="btn btn-primary">添加用户</a>
    {% endif %}
    <table class="table table-bordered table-striped">
        <thead>
              <tr>
                   <th>序号</th>
                   <th>姓名</th>
                   <th>角色</th>
                   <th>操作</th>
              </tr>
        </thead>
       <tbody>
            {% for user in user_list %}
            <tr>
                 <td>{{ forloop.counter }}</td>
                 <td>{{ user.name }}</td>
                 <td>
                     {% for role in user.roles.all %}
                     {{ role.title }}
                     {% endfor %}

                 </td>

                 <td>
                     {% if per.delete %}
                      <a href="/users/delete/{{ user.pk }}" class="btn btn-danger">删除</a>
                     {% endif %}
                     {% if per.edit %}
                     <a href="" class="btn btn-warning">编辑</a>
                     {% endif %}
                 </td>
            </tr>
            {% endfor %}

       </tbody>
    </table>


{% endblock %}

 

 

4.项目设置文件settings.py

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'app01.apps.App01Config',
    "rbac.apps.RbacConfig"
]

MIDDLEWARE = [
    'django.middleware.security.SecurityMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.middleware.common.CommonMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.clickjacking.XFrameOptionsMiddleware',
    "rbac.service.rbac.ValidPermission"
]

 项目设置文件urls.py

"""s9day82_rbac URL Configuration

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


from app01 import views
urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^users/$', views.users),
    url(r'^users/add', views.add_user),
    url(r'^roles/', views.roles),
    url(r'^login/', views.login),
]