报障系统之权限管理

表结构设计

from django.db import models


class User(models.Model):
    """
    用户表
    """
    username = models.CharField(verbose_name='用户名', max_length=32)
    password = models.CharField(verbose_name='密码', max_length=64)
    email = models.EmailField(verbose_name='邮箱')

    def __str__(self):
        return self.username


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

    def __str__(self):
        return self.caption


class User2Role(models.Model):
    """
    用户角色关系表
    """
    user = models.ForeignKey(User, verbose_name='用户', related_name='roles')
    role = models.ForeignKey(Role, verbose_name='角色', related_name='users')

    def __str__(self):
        return '%s-%s' % (self.user.username, self.role.caption,)


class Menu(models.Model):
    """
    菜单表
    """
    caption = models.CharField(verbose_name='菜单名称', max_length=32)
    parent = models.ForeignKey('self', verbose_name='父菜单', related_name='p', null=True, blank=True)

    def __str__(self):
        prev = ""
        parent = self.parent
        while True:
            if parent:
                prev = prev + '-' + str(parent.caption)
                parent = parent.parent
            else:
                break
        return '%s-%s' % (prev, self.caption,)


class Permission(models.Model):
    """
    权限
    """
    caption = models.CharField(verbose_name='权限', max_length=32)
    url = models.CharField(verbose_name='URL正则', max_length=128)
    menu = models.ForeignKey(Menu, verbose_name='所属菜单', related_name='permissions',null=True,blank=True)

    def __str__(self):
        return "%s-%s" % (self.caption, self.url,)


class Action(models.Model):
    """
    操作:增删改查
    """
    caption = models.CharField(verbose_name='操作标题', max_length=32)
    code = models.CharField(verbose_name='方法', max_length=32)

    def __str__(self):
        return self.caption


class Permission2Action2Role(models.Model):
    """
    权限操作关系表
    """
    permission = models.ForeignKey(Permission, verbose_name='权限URL', related_name='actions')
    action = models.ForeignKey(Action, verbose_name='操作', related_name='permissions')
    role = models.ForeignKey(Role, verbose_name='角色', related_name='p2as')

    class Meta:
        unique_together = (
            ('permission', 'action', 'role'),
        )

    def __str__(self):
        return "%s-%s-%s" % (self.permission, self.action, self.role,)
权限管理 models.py

url配置,用到路由分发include

"""baozhang 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,include
from django.contrib import admin
from app01 import views

urlpatterns = [
    url(r'^admin/', admin.site.urls),
    url(r'^app02/', include('app02.urls')),
]
主urls.py
"""baozhang 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,include
from django.contrib import admin
from app02 import views

urlpatterns = [
    url(r'^test/', views.test),
]
app02.urls.py

views.py

from django.shortcuts import render,HttpResponse
from app02 import models
from django.db.models import Count
def test(request):
    # user_list = models.User.objects.filter(id=id)
    # user_role_list = models.User2Role.objects.filter(user_id=1).values('user_id','user__username','role__caption')
    role = models.User2Role.objects.filter(user_id=1).values('role')
    obj = models.Permission2Action2Role.objects.filter(role__in=role).values('permission_id','permission__url').annotate(x=Count('id'))
    for row in obj:
        print(row)
    return HttpResponse('ok')

 1.权限测试

在项目的根目录创建middleware,新建一个md.py文件,创建一个M1的类,定义一个process_request函数,做进一步操作

这里要注意,新建的中间件里的类要继承原有中间件里的类的函数

url(r'^auth-login.html$', views2.login),
url(r'^auth-index.html$', views2.index),
url定义路由
from django.middleware.clickjacking import XFrameOptionsMiddleware这是原有的中间件
from django.utils.deprecation import MiddlewareMixin

class XFrameOptionsMiddleware(MiddlewareMixin):
  pass 具体内容略
说明要导入这个模块:
from django.utils.deprecation import MiddlewareMixin
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',
    'middleware.md.M1',
]
在settings.py添加中间件middleware.md.M1
#from django.middleware.clickjacking import XFrameOptionsMiddleware
from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import render,HttpResponse
import re
class M1(MiddlewareMixin):
    def process_request(self,request,*args,**kwargs):
        valid = ['/auth-login.html','/index.html','/']
        if request.path_info not in valid:
            action = request.GET.get('md')  # 获取GET
            user_permission_dict = request.session.get('user_permission_dict')
            if not user_permission_dict:  # 如果没有用户权限
                return HttpResponse('无权限')
            """
        user_permission_dict = {
            '/auth-index.html':["GET","POST",'DEL',"Edit"],
            '/index.html':["GET","POST",'DEL',"Edit"],
            '/order.html':["GET","POST",'DEL',"Edit"],
            # '/ah-index.html':["GET","POST",'DEL',"Edit"],
            # '/order.html':["GET","POST",'DEL',"Edit"],
            '/index-(d+).html':["GET","POST",'DEL',"Edit"],
        }
            """
            flag = False
            for k,v in user_permission_dict.items():
                if re.match(k,request.path_info):#如果url(/index-(d+).html)匹配成功,然后继续匹配后面的方法
                    if action in v:#后面的方法匹配成功
                        flag = True
                        break#直接退出循环
            if not flag:
                return HttpResponse('无权限')
                # re.match('/index-(d+).html','/index-222.html')
            # action_list = user_permission_dict.get(request.path_info)
            # print(action_list)
            # if not action_list:  # 如果值不在这个action_list里
            #     return HttpResponse('无权限')
            # if action not in action_list:
            #     return HttpResponse('无权限')
定义中间件M1(利用中间件做权限过滤比装饰器好一点)
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title></title>
</head>
<body>
    <form method="POST" action="/auth-login.html">
        {% csrf_token %}
        <input type="text" name="user" />
        <input type="submit" value="提交">
    </form>

</body>
</html>
login2.html

2.开发一个权限相关组件

2.1插入数据:

from django.contrib import admin
from app02 import models

admin.site.register(models.Permission2Action2Role)
admin.site.register(models.Permission)
admin.site.register(models.Action)
admin.site.register(models.Menu)
admin.site.register(models.Role)
admin.site.register(models.User)
admin.site.register(models.User2Role)
先在admin.py注册所有的数据表

然后登录Django后台管理:

http://127.0.0.1:8000/admin/ 输入用户名密码,登录进去,然插入测试数据(略)

相关推荐