s11 day106-107 RBAC模块

一、登录 把权限存在session中

1. rbac models

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=128)

    def __str__(self):
        return self.title


class Role(models.Model):
    """
    角色
    """
    title = models.CharField(verbose_name='角色名称', max_length=32)
    permissions = models.ManyToManyField(verbose_name='拥有的所有权限', to='Permission', blank=True)

    def __str__(self):
        return self.title


class UserInfo(models.Model):
    """
    用户表
    """
    name = 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)

    def __str__(self):
        return self.name

  

 2. web models

from django.db import models


class Customer(models.Model):
    """
    客户表
    """
    name = models.CharField(verbose_name='姓名', max_length=32)
    age = models.CharField(verbose_name='年龄', max_length=32)
    email = models.EmailField(verbose_name='邮箱', max_length=32)
    company = models.CharField(verbose_name='公司', max_length=32)

    def __str__(self):
        return self.name

    class Meta:
        verbose_name_plural = "客户表"

class Payment(models.Model):
    """
    付费记录
    """
    customer = models.ForeignKey(verbose_name='关联客户', to='Customer')
    money = models.IntegerField(verbose_name='付费金额')
    create_time = models.DateTimeField(verbose_name='付费时间', auto_now_add=True)

    class Meta:
        verbose_name_plural = "支付表"
#########权限相关###########
PERMISSION_SESSION_KEY ="permission_list"

VALID_URL=[
    "^/login/$",
    "^/admin/.*",

]

  

from django.conf.urls import url
from web.views import customer
from web.views import payment
from web.views import login

urlpatterns = [

    url(r'^customer/list/$', customer.customer_list),
    url(r'^customer/add/$', customer.customer_add),
    url(r'^customer/edit/(?P<cid>d+)/$', customer.customer_edit),
    url(r'^customer/del/(?P<cid>d+)/$', customer.customer_del),
    url(r'^customer/import/$', customer.customer_import),
    url(r'^customer/tpl/$', customer.customer_tpl),

    url(r'^payment/list/$', payment.payment_list),
    url(r'^payment/add/$', payment.payment_add),
    url(r'^payment/edit/(?P<pid>d+)/$', payment.payment_edit),
    url(r'^payment/del/(?P<pid>d+)/$', payment.payment_del),

    url(r"^login/",login.login)
]

 

 

from  django.shortcuts import render,redirect
from rbac import models
# from luffy_permission.settings import PERMISSION_SESSION_KEY
from django.conf import settings

def login(request):
    if request.method == "GET":

        return render(request, 'login.html')

    #1. 获取提交的用户名和密码
    user = request.POST.get("user")
    user = request.POST.get('user')

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

    #2.检验用户是否合法
    obj = models.UserInfo.objects.filter(name=user, password=pwd).first()
    print(obj)

    if not obj:
        return render(request, 'login.html', {'msg': '用户名或密码错误'})

    #3获取用户信息和权限信息写入session
    permission_list =obj.roles.filter(permissions__url__isnull = False).values('permissions__url').distinct()
    print(permission_list)
    for item  in permission_list:
        print(item)
    request.session['user_info'] = {'id':obj.id,'name':obj.name}

    request.session[settings.PERMISSION_SESSION_KEY] = list(permission_list)
    return redirect('/customer/list/')

 二、中间件

https://www.cnblogs.com/yuanchenqi/articles/9036467.html?tdsourcetag=s_pcqq_aiomsg   (session知识点)

from django.utils.deprecation import MiddlewareMixin
from django.shortcuts import redirect,HttpResponse
from luffy_permission import settings
import re
class RbacMiddleware(MiddlewareMixin):
    #权限控制的中间件
    def process_request(self,request):
        #权限控制
        #1. 获取当前请求url
        current_url =request.path_info

        #1.5 白名单处理
        for reg in settings.VALID_URL:
            import re
            if re.match(reg,current_url):
                return None

        #2. 获取当前用户session所有权限
        permission_list =request.session.get(settings.PERMISSION_SESSION_KEY)
        if not permission_list:
            return redirect("/login")

        #3.进行权限校验

        print(current_url)
        print(permission_list)
        flag =False
        for item in permission_list:
            reg ="^%s$" %         item.get("permissions__url")
            import re
            if re.match(reg,current_url):
                flag=  True
                break
        if not flag:
            return HttpResponse("无权访问")

  

 三 、为客户添加菜单 (二级菜单,一级菜单)

修改 models

class Permission(models.Model):
    """
    权限表
    """
    title = models.CharField(verbose_name='标题', max_length=32)
    url = models.CharField(verbose_name='含正则的URL', max_length=128)

    is_menu =models.BooleanField(verbose_name="是否可以作为菜单",default=False)
    icon =models.CharField(max_length=32,null=True,blank=True)
   红色即为增加字段

略  

四、生成组件.

1.设置一个初始化组件 ,将登陆后的权限信息和菜单信息放入session

from django.conf import settings


def init_permission(request,user):
    """
    权限和菜单信息初始化,以后使用时,需要在登陆成功后调用该方法将权限和菜单信息放入session
    :param request:
    :param user:
    :return:
    """

    # 3. 获取用户信息和权限信息写入session
    permission_queryset = user.roles.filter(permissions__url__isnull=False).values('permissions__url',
                                                                                  'permissions__is_menu',
                                                                                  'permissions__title',
                                                                                  'permissions__icon',
                                                                                  ).distinct()


    menu_list = []
    permission_list = []

    for row in permission_queryset:
        permission_list.append({'permissions__url': row['permissions__url']})

        if row['permissions__is_menu']:
            menu_list.append(
                {'title': row['permissions__title'], 'icon': row['permissions__icon'], 'url': row['permissions__url']})

    request.session[settings.PERMISSION_SESSION_KEY] = permission_list
    request.session[settings.MENU_SESSION_KEY] = menu_list

2.登陆界面 ,留意红色字体,在调用权限组件

from django.shortcuts import render, redirect,HttpResponse
from rbac import models
from rbac.service.init_permission import init_permission
from django.conf import settings


def login(request):
    """
    用户登陆
    :param request:
    :return:
    """
    if request.method == 'GET':
        return render(request,'login.html')

    # 1. 获取提交的用户名和密码
    user = request.POST.get('user')
    pwd = request.POST.get('pwd')

    # 2. 检验用户是否合法
    obj = models.UserInfo.objects.filter(name=user,password=pwd).first()
    if not obj:
        return render(request, 'login.html',{'msg':'用户名或密码错误'})
    request.session['user_info'] = {'id': obj.id, 'name': obj.name}
init_permission(request,obj)
return redirect('/student/') def student(request): return render(request,'student.html') def student_add(request): return render(request, 'student_add.html')

3.中间件组件的整合

from django.utils.deprecation import MiddlewareMixin
from django.conf import settings
from django.shortcuts import redirect,HttpResponse
import re

class RbacMiddleware(MiddlewareMixin):
    """
    权限控制的中间件
    """

    def process_request(self, request):
        """
        权限控制
        :param request:
        :return:
        """
        # 1. 获取当前请求URL
        current_url = request.path_info

        # 1.5 白名单处理
        for reg in settings.VALID_URL:
            if re.match(reg,current_url):
                return None

        # 2. 获取当前用户session中所有的权限
        permission_list = request.session.get(settings.PERMISSION_SESSION_KEY)
        if not permission_list:
            return redirect('/login/')

        # 3. 进行权限校验
        flag = False
        for item in permission_list:
            reg = "^%s$" % item.get('permissions__url')
            if re.match(reg, current_url):
                flag = True
                break
        if not flag:
            return HttpResponse('无权访问')
原文地址:https://www.cnblogs.com/mengbin0546/p/9503642.html