权限管理代码

settings.py

"""
Django settings for s8day88quanxian project.

Generated by 'django-admin startproject' using Django 1.11.9.

For more information on this file, see
https://docs.djangoproject.com/en/1.11/topics/settings/

For the full list of settings and their values, see
https://docs.djangoproject.com/en/1.11/ref/settings/
"""

import os

# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))


# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/

# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '+0ec#ojnu8uc(5w#lx#9fci#ucm*pr2m66hl1*1wvjo(4a@97@'

# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True

ALLOWED_HOSTS = []


# Application definition

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.M1',
]

from django.contrib.sessions.middleware import SessionMiddleware
from django.contrib.sessions.backends import db
ROOT_URLCONF = 's8day88quanxian.urls'

TEMPLATES = [
    {
        'BACKEND': 'django.template.backends.django.DjangoTemplates',
        'DIRS': [os.path.join(BASE_DIR, 'templates')]
        ,
        'APP_DIRS': True,
        'OPTIONS': {
            'context_processors': [
                'django.template.context_processors.debug',
                'django.template.context_processors.request',
                'django.contrib.auth.context_processors.auth',
                'django.contrib.messages.context_processors.messages',
            ],
        },
    },
]

WSGI_APPLICATION = 's8day88quanxian.wsgi.application'


# Database
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.sqlite3',
        'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
        'OPTIONS': {
        'timeout': 20,
    }
    }
}


# Password validation
# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators

AUTH_PASSWORD_VALIDATORS = [
    {
        'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
    },
    {
        'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
    },
]


# Internationalization
# https://docs.djangoproject.com/en/1.11/topics/i18n/

LANGUAGE_CODE = 'en-us'

TIME_ZONE = 'UTC'

USE_I18N = True

USE_L10N = True

USE_TZ = True


# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.11/howto/static-files/

STATIC_URL = '/static/'
View Code

urls.py

"""s8day88quanxian 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'^$', views.login),
    url(r'^login/$', views.login),
    url(r'^users/$', views.users),
    url(r'^orders/$', views.orders),
    url(r'^orders/add/$', views.orders_add),
    url(r'^orders/delete/$', views.orders_delete),
    url(r'^orders/edit$', views.orders_edit),
    url(r'^users/add/$', views.users_add),
    url(r'^users/delete/$', views.users_delete),
    url(r'^users/edit/$', views.users_edit),
    url(r'^logout/$', views.logout),
    url(r'^m1/$', views.m1),
    url(r'^m2/$', views.m2),

]
View Code

app01应用下面的views.py

import re
from django.shortcuts import render,redirect,HttpResponse

# Create your views here.
from rbac.models import *
from rbac.service.base import Permissions
def login(request):
    if request.method=="GET":
        return render(request,"login.html")
    else:
        user=request.POST.get("user")
        pwd=request.POST.get("pwd")
        user=UserInfo.objects.filter(name=user,pwd=pwd).first()
        if user:
            request.session["user_id"]=user.pk

            from rbac.service.initial import initial_session
            initial_session(request,user)

            return HttpResponse("登录成功")
        else:
            return redirect("/login/")

def users(request):


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

def orders(request):

    code_list=request.code_list
    Per = Permissions(code_list)
    return render(request,"orders.html",locals())
def orders_add(request):
    return HttpResponse("欢迎来到添加订单页面")
def orders_delete(request):
    return HttpResponse("删除成功")
def orders_edit(request):
    return HttpResponse("编辑页面")

def users_add(request):
    return HttpResponse("添加用户")
def users_delete(request):
    return HttpResponse("删除用户")

def users_edit(request):
    return HttpResponse("编辑用户")
def logout(request):
    request.session.flush()
    return redirect("/login/")

def m1(request):
    """
    [{'id': 2, 'url': '/orders/', 'title': '订单列表', 'pid': None, 'menu_id': 2, 'menu_caption': '订单管理'},
    {'id': 3, 'url': '/users/add/', 'title': '添加用户', 'pid': 8, 'menu_id': 1, 'menu_caption': '用户角色管理'},
    {'id': 4, 'url': '/users/delete', 'title': '删除用户', 'pid': 8, 'menu_id': 1, 'menu_caption': '用户角色管理'},
    {'id': 6, 'url': '/orders/add/', 'title': '添加订单', 'pid': 1, 'menu_id': 2, 'menu_caption': '订单管理'},
    {'id': 7, 'url': '/orders/delete', 'title': '删除订单', 'pid': 1, 'menu_id': 2, 'menu_caption': '订单管理'},
    {'id': 9, 'url': '/users/', 'title': '用户列表', 'pid': None, 'menu_id': 1, 'menu_caption': '用户角色管理'}]
    """

    return render(request, "m1.html", locals())
    # menu_dict={
    #   1:{
    #       "title":"菜单一",
    #       "active": False ,
    #       "children":[
    #           {"title":"查看用户列表","url":"xxxxxxxx","active":False} ,
    #           {"title":"添加用户","url":"xxxxxxx","active":False}
    #       ]},
    #     2:{
    #         "title":"菜单二",
    #         "active":True,
    #         "children":[
    #             {"title":"查看订单","url":"xxxxxxx","active":True},
    #             {"title":"添加订单","url":"xxxxxxx","active":False},
    #         ]
    #     }
    # }




def m2(request):


    # menu_dict={
    #   1:{
    #       "title":"菜单一",
    #       "active":True ,
    #       "children":[
    #           {"title":"查看用户列表","url":"xxxxxxxx","active":False} ,
    #           {"title":"添加用户","url":"xxxxxxx","active":True}
    #       ]},
    #
    #
    #     2:{
    #         "title":"菜单二",
    #         "active":False,
    #         "children":[
    #             {"title":"查看订单","url":"xxxxxxx","active":False},
    #             {"title":"添加订单","url":"xxxxxxx","active":False},
    #         ]
    #     }
    # }

    return render(request, "m2.html", locals())
View Code

rbac应用

service文件夹下的 

   base.py

class Permissions(object):
    def __init__(self,code_list):
        self.code_list=code_list
    def add(self):
        return "add" in self.code_list
    def delete(self):
        return "delete" in self.code_list
    def edit(self):
        return "edit" in self.code_list
    def list(self):
        return "list" in self.code_list
View Code

    initial.py

def initial_session(request,user):
      # 方式一:
#       # 获取当前登录用户的所有权限
#       permission_info = user.roles.all().values("permission__url", "permission__title").distinct()
#
#
#       temp = []
#       for i in permission_info:
#         temp.append(i["permission__url"])
#       request.session["permission_list"] = temp
# 方式二
# 创建一个数据格式:包含所有权限,权限所在组,权限编号
      permission_info = user.roles.all().values( "permission__id",
                                                 "permission__url",
                                                 "permission__title",
                                                "permission__permission_group_id",
                                                 "permission__code",
                                                 "permission__permission_group__menu__id",
                                                 "permission__permission_group__menu__caption",
                                                 "permission__parent_id"
                                                 ).distinct()


     # 构建数据
    # 将这个列表转换为字典的形式
      permission_list=[]

      for permission_item in permission_info:
          temp={
              "id":permission_item["permission__id"],
              "url":permission_item["permission__url"],
              "title":permission_item["permission__title"],
              "pid":permission_item["permission__parent_id"],
              "menu_id":permission_item["permission__permission_group__menu__id"],
              "menu_caption":permission_item["permission__permission_group__menu__caption"],

          }
          permission_list.append(temp)

     # 将自己重构的这个列表注册到session中
      request.session["permission_list"]= permission_list



     # 将登录用户的所有权限写入到session中
      permission_dict = {}
      for item in permission_info:

          group_id = item["permission__permission_group_id"]

          if group_id in permission_dict:

              permission_dict[group_id]['urls'].append(item["permission__url"])
              permission_dict[group_id]['codes'].append(item["permission__code"])
          else:

              permission_dict[group_id] = {
                  'urls': [item["permission__url"]],
                  'codes': [item["permission__code"]]
              }

          request.session["permission_dict"] = permission_dict
View Code

   rbac.py

from django.utils.deprecation import MiddlewareMixin

from django.shortcuts import redirect,HttpResponse,render

class M1(MiddlewareMixin):
    def process_request(self,request):


        current_path=request.path_info
        print(current_path)

        valid_url_menu=["/login/","/reg/","/logout/","/admin/.*",'/$']

        import re
        for valid_url in valid_url_menu:
            ret=re.match(valid_url,current_path)
            if ret:
                return None
            # 取出当前登录用户所有的权限列表
            # 方式1
        # permission_list=request.session.get("permission_list")
        # 方式2:


         # 验证用户是否登录
        user_id=request.session.get("user_id")
        print(user_id)
        if not user_id:
            return redirect("/login/")
        import re
        permission_dict=request.session.get("permission_dict")
        print(permission_dict)
        for item in permission_dict.values():
            permission_url=item["urls"]
            permission_code=item["codes"]

            for url in permission_url:
                url="^%s$"%url
                ret_url=re.match(url,current_path)
                if ret_url:
                    request.code_list=permission_code
                    return None    # return none代表直接通过

        return HttpResponse("没有权限")











    # 方式一
        # flag=False
        # for permission_url in permission_list:
        #     # permission_url="^{}$".format(permission_url)    #字符串格式化
        #     permission_url="^%s$"%permission_url
        #     ret=re.match(permission_url,current_path)
        #
        #     if ret:
        #         print(ret)
        #         flag=True
        #         break
        # if not flag:
        #     return HttpResponse("没有权限")
View Code

templatetags文件夹下的

my_tags.py

# 自己写的自定义标签
import re
from django import template

register=template.Library()

@register.inclusion_tag("menu.html")
def get_menu(request):
    permission_list = request.session.get("permission_list")
    # 判断是否可以放到菜单栏中
    temp_dict={}
    for item in permission_list:      #permission_list是我在inital中构建的数据,他是一个列表,里面是一组组的键值对
        print(item)
        if not item["pid"]:
            item["active"]=False
            temp_dict[item["id"]]=item
    # 判断active的状态
    current_path=request.path_info

    for item in permission_list:
        print(current_path,item["url"])
        pid=item["pid"]
        url="^%s$"%item["url"]

        if re.match(url,current_path):
            if not pid:
                temp_dict[item["id"]]["active"]=True
            else:
                temp_dict[pid]["active"]=True





            # 将temp_dict转换为menu_dict
    menu_dict = {}
    for item in temp_dict.values():
        if item["menu_id"] in menu_dict:
            temp = {"title": item["title"], "url": item["url"], "active": item["active"]},
            menu_dict[item["menu_id"]]["children"].appen(temp)
            if item["active"]:
                menu_dict[item["menu_id"]]["active"] = True
        else:
            menu_dict[item["menu_id"]] = {

                "active": item["active"],
                "menu_caption": item["menu_caption"],
                "children": [
                    {"title": item["title"], "url": item["url"], "active": item["active"]},
                ]
            }


    return{"menu_dict":menu_dict}
View Code

admin.py

from django.contrib import admin

# Register your models here.

from .models import *

class  UserInfoConfig(admin.ModelAdmin):
    list_display = ["id","name","email"]
    # list_display_links = ["name"]
    # ordering = ["id"]
    # search_fields = ["name"]
    # list_filter =["roles"]
    # list_editable = ["name"]
    # fields = ["name"]
    # exclude = ["name"]     #和files相反,意思就是除了这个字段,其余字段都展示
    # readonly_fields = ["name"]   #只读,只让看不让动
    # fieldsets = (
    #     ('基本数据', {
    #         'fields': ('name', 'email')
    #     }),
    #
    #     ('其他', {
    #         'classes': ('collapse', 'wide', 'extrapretty'),  # 'collapse','wide', 'extrapretty'
    #         'fields': ('roles',),
    #     }),
    # )
    def foo(self,request,queryset):
        print(queryset)
        queryset.update(email="lan@qq.com")
    foo.short_description = "中文显示自定义Actions"
    actions = [foo,]
admin.site.register(UserInfo,UserInfoConfig)




# admin.site.register(UserInfo)
# admin.site.register(Role)
# admin.site.register(PermissionGroup)
# admin.site.register(Menu)
class RoleConfig(admin.ModelAdmin):
    list_display = ["id","title"]
admin.site.register(Role,RoleConfig)

class PermissionGroupConfig(admin.ModelAdmin):
    list_display = ["id","caption","menu"]
    ordering = ["id"]
admin.site.register(PermissionGroup, PermissionGroupConfig)

class PermissionConfig(admin.ModelAdmin):
    list_display = ["id","title","url","permission_group","code","parent"]
    ordering = ["id"]
admin.site.register(Permission,PermissionConfig)
class MenuConfig(admin.ModelAdmin):
    list_display = ["id","caption"]
admin.site.register(Menu,MenuConfig)
View Code

models.py

from django.db import models

# Create your models here.

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

    def __str__(self):
        return self.name

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

    def __str__(self):
        return self.title

class Menu(models.Model):
    caption=models.CharField(max_length=32)
    def __str__(self):
        return self.caption

class Permission(models.Model):
    url=models.CharField(max_length=32)
    title=models.CharField(max_length=32)
    permission_group=models.ForeignKey(to="PermissionGroup",default=1)
    code=models.CharField(max_length=32,default="")
    parent=models.ForeignKey("self",null=True,blank=True)

    def __str__(self):
        return self.title

class PermissionGroup(models.Model):
    caption=models.CharField(max_length=32)
    menu=models.ForeignKey(to="Menu",default=1)

    def __str__(self):
        return self.caption
View Code

templates下

base.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css">
    <title>Title</title>
    <style>
     .active{
        color: red;
     }
     .hide {
        display: none;
     }
    </style>
</head>
<body>
{% load my_tags  %}
{% include "nav.html" %}
 <div class="container-fluid" style="margin-top: 70px">
      <div class="row">
           {% get_menu request %}
            <div class="col-md-9">
           {% block con %}

           {% endblock %}
            </div>
      </div>

 </div>

</body>
</html>
View Code

login.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="" method="post">
    {% csrf_token %}
    <p>用户名<input type="text" name="user"></p>
    <p>密码<input type="password" name="pwd"></p>
    <input type="submit">
</form>
</body>
</html>
View Code

m1.html

{% extends "base.html" %}
{% block con %}
<div class="col-sm-6 col-md-6 sidebar">内容一</div>
{% endblock %}
View Code

m2.html

{% extends "base.html" %}
{% block con %}
<div class="col-sm-6 col-md-6 sidebar">内容二</div>
{% endblock %}
View Code

menu.html

    <div class="col-sm-3 col-md-2 sidebar">
       {% for item in menu_dict.values %}

           <div>
              {{ item.menu_caption }}</div>
               {% if item.active %}
                    <ul class="nav nav-sidebar">
                     {% else %}
                       <ul class="nav hide nav-sidebar">

               {% endif %}
                 {% for son in item.children  %}
                    {% if son.active %}
                       <li><a href="{{ son.url }}" class="active">{{ son.title }}</a></li>
                          {% else %}
                           <li><a href="{{ son.url }}" >{{ son.title }}</a></li>
                    {% endif %}
                 {% endfor %}

            </ul>
       {% endfor %}


    </div>
View Code

nav.html

<nav class="navbar navbar-inverse navbar-fixed-top" style="background-color: #336699; " >
      <div class="container-fluid">
        <div class="navbar-header" >
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#navbar" aria-expanded="false" aria-controls="navbar">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
          </button>
          <a class="navbar-brand" href="#">菜单系列</a>
        </div>
        <div id="navbar" class="navbar-collapse collapse">


        </div>
      </div>
    </nav>
View Code

orders.html

{% extends "base.html" %}
{% block con %}
    <div class="">


            {% if Per.add %}

                <p><a href="/orders/add">
                    <button class="btn btn-primary pull-right">添加订单</button>
                </a></p>
            {% endif %}




</div>

<table class="table table-striped"  border="1">
    <tr>
        <td>订单号</td>
        <td>订单日期</td>
        <td>商品名称</td>
    </tr>
    <tr>
        <td>123</td>
        <td>2012-12-2</td>
        <td>dawei</td>
    </tr>
</table>
{% endblock %}
<div class="">


            {% if Per.add %}

                <p><a href="/orders/add">
                    <button class="btn btn-primary pull-right">添加订单</button>
                </a></p>
            {% endif %}




</div>

<table class="table table-striped"  border="1">
    <tr>
        <td>订单号</td>
        <td>订单日期</td>
        <td>商品名称</td>
    </tr>
    <tr>
        <td>123</td>
        <td>2012-12-2</td>
        <td>dawei</td>
    </tr>
</table>
View Code

users.html

{% extends "base.html" %}
{% block  con %}
    <h1>我的妈呀</h1>
{% endblock %}
View Code
原文地址:https://www.cnblogs.com/1996-11-01-614lb/p/8545159.html