zoukankan      html  css  js  c++  java
  • Django--权限组件

    创建组件

    需求分析:

     创建独立app, rbac        

    ##注意:

      app创建后需要注册到setting.py中

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

    设计权限表

    方案1:

    创建用户表和创建权限表,然后两个表通过一个用户可能有多各权限 然后一个权限可以属于多个用户,所以两张表创建多对多关系,但是存在很多用户有相同的权限字段,所以参考方案二。

    方案2:

    创建用户表、创建权限表和角色表,为每个角色添加权限,然后用户通过角色获取自己的权限,分析如下所示

         
                用户表:
                    ID          username        password    ....
                     1           番禺                 123
                     2           夹缝                 123
                     3           果冻                 123
                     4           鲁宁                 123
                     
                     
                角色表:
                    ID          title 
                     1            CEO
                     2            CTO
                     4            COO
                     5            部门经理
                     6            技术员
                     
                用户和角色关系表:
                    用户ID       角色ID
                      1            1
                      1            2
                      1            4
                      2            5
                      3            6
                      4            6
            
                权限表:
                    ID          url                         title
                     1         /index/                      首页
                     2         /userinfo/                   用户列表
                     3         /userinfo/add/               添加用户
                     4         /userinfo/del/(d+)/         删除用户
                     5         /userinfo/edit/(d+)/        修改用户
            
                
                角色权限关系表:
                    角色ID           权限ID 
                      1                1

    具体表设计如下所示:

    from django.db import models
    
    class Permission(models.Model):
        """
        权限表
        """
        title = models.CharField(verbose_name='标题',max_length=32)
        url = models.CharField(verbose_name="含正则URL",max_length=64)
        is_menu = models.BooleanField(verbose_name="是否是菜单")
    
        class Meta:
            verbose_name_plural = "权限表"
    
        def __str__(self):
            return self.title
    
    class User(models.Model):
        """
        用户表
        """
        username = models.CharField(verbose_name='用户名',max_length=32)
        password = models.CharField(verbose_name='密码',max_length=64)
        email = models.CharField(verbose_name='邮箱',max_length=32)
    
        roles = models.ManyToManyField(verbose_name='具有的所有角色',to="Role",blank=True)
        class Meta:
            verbose_name_plural = "用户表"
    
        def __str__(self):
            return self.username
    
    class Role(models.Model):
        """
        角色表
        """
        title = models.CharField(max_length=32)
        permissions = models.ManyToManyField(verbose_name='具有的所有权限',to='Permission',blank=True)
        class Meta:
            verbose_name_plural = "角色表"
    
        def __str__(self):
            return self.title

     然后通过管理类同步数据库,添加数据。

    3. 权限录入:
            CEO:番禺
                /userinfo/
                /userinfo/add/
                /userinfo/edit/(d+)/
                /userinfo/del/(d+)/
                /order/
                /order/add/
                /order/edit/(d+)/
                /order/del/(d+)/
            总监:鲁宁
                /userinfo/
                /userinfo/add/
                /order/
                /order/add/
            经理:肾松
                /userinfo/
                /order/
            业务员:肾松,文飞,成栋
                /order/

    配置用户调用接口

    1. 本地化用户权限

    在rbac中创建一个初始化文件,用于本地化权限信息,使调用者方便调用

    from django.conf import settings
    
    def init_permission(request,user):
        """
        本地化用户权限"""
        # 获取当前用户所有权限(重)
        permission_list = user.roles.values('permissions__url').distinct()
        request.session[settings.PERMISSION_LIST] = [url['permissions__url'] for url in permission_list]

    2. 通过中间键进行用户请求url过滤

    settings.py中

    
    
    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.middleware.PermissionMiddleware', # 将添加的中间件配置到settings中
    ]
    #####################confirm###################
    SESSION_KEY = 'auth_user'
    PERMISSION_LIST = 'permission_list'
    
    INVALIDATION_LIST = [
        '/admin.*',
        '/login/',
        '/register/',
    ]

    创建middleware.py

    # encoding:utf-8
    # Author:"richie"
    # Date:11/7/2017
    import re
    from django.conf import settings
    from django.shortcuts import HttpResponse,redirect
    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 PermissionMiddleware(MiddlewareMixin):
    
        def process_request(self, request):
    
            current_path = request.path_info
    
    
            for url in settings.INVALIDATION_LIST:
                if re.match(url,current_path):
                    return None
    
            permission_list = request.session.get(settings.PERMISSION_LIST)
    
            if not permission_list:
                return redirect('/login/')
    
            flag = False
    
            for url in permission_list:
                regular = "^{0}$".format(url)  # 因为添加url的时候没有添加严格匹配的规则,所以在这里转格式
                if re.match(regular,current_path):
                    flag = True
                    break
    
            if not flag:
                # 没有匹配上
                return HttpResponse('无权访问')

    权限组件使用

    分配url,

    from django.conf.urls import url
    from app01 import views
    urlpatterns = [
        url(r'^login/', views.login, name='login'),
        url(r'^index/', views.home, name='home'),
        url(r'^userinfo/', views.home, name='home'),
        url(r'^userinfo/add', views.home, name='home'),
        url(r'^order/', views.home, name='home'),
        url(r'^order/add', views.home, name='home'),
    ]

    定义视图函数:

    from django.shortcuts import render,redirect
    from django.conf import settings
    from rbac.models import User
    from rbac.service import init_permission
    # Create your views here.
    
    class UserLoginForm(forms.ModelForm):
        """
        定义用户登录的from表单
        """
        class Meta:
            model  = models.User
            fields = ['username','password']
    
    def login(request):
        if request.method == 'POST':
            # 获取用户from表单数据
            login_form = forms.UserLoginForm(request.POST)
            # 数据格式验证
            if login_form.is_valid():
                #用户认证
                username = login_form.cleaned_data.get('username')
                password = login_form.cleaned_data.get('password')
                # 用户数据数据库验证
                user =User.objects.filter(username=username,password=password).first()
                if user:
                    #初始化权限系统
                    init_permission(request,user)
                    # 添加用户信息
                    request.session[settings.SESSION_KEY] = {'uid':user.id,'username':username}
                    return redirect('/home/')
                else:
                    # 登录失败  添加错误信息
                    login_form.errors.update({'user_error': '用户名或密码错误'})
        else:
            login_form = forms.UserLoginForm()
    
        return render(request, 'login.html',{'form':login_form})
    
    def home(request):
        """
        主页面
        :param request: 
        :return: 
        """
        
        #获取用户名信息
        username = request.session.get(settings.SESSION_KEY).get('username')
        return render(request,'home.html',locals())

    3. 定义模板页面

    login.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">
        <title>Title</title>
    </head>
    <body>
    
    <form method="post" novalidate>{% csrf_token %}
        {{ form.errors.user_error }}
        {% for filed in form %}
            <p>{{ filed.label_tag }}{{ filed }}</p>
            <p>{{ filed.errors.as_text }}</p>
        {% endfor %}
    
        <input type="submit" value="提交">
    </form>
    
    </body>
    </html>

    定义home.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">
        <title>Title</title>
    </head>
    <body>
    {{ username }}
    </body>
    </html>
  • 相关阅读:
    转载:div和flash层级关系问题
    转载:页面加载swf插件:swfobject
    C++ code:浮点数的比较(Floating-Pointing Number Comparison)
    Deep Learning系统实训之三:卷积神经网络
    C++ code:指针类型(pointer types)
    Linear Algebra(未完待续)
    Deep Learning系统实训之二:梯度下降原理
    C++ code:向量操作之添加元素
    Deep Learning系统实训之一:深度学习基础知识
    机器学习与优化关系、凸集、凸函数简介
  • 原文地址:https://www.cnblogs.com/richiewlq/p/7799639.html
Copyright © 2011-2022 走看看