Django中已经为我们设置好了基本的权限系统,在定义好model同步数据库后,在每个库下面都会有一张 'auth_permission' 表。该表里面记录了每条权限的描述(name字段,can do something,会显示在后台付权限的列表中)和名字(codename字段,代码逻辑中检查权限使用,该字段会在权限验证函数perm_check中被 'request.user.has_perm' 方法调用,来判断是否通过验证。)

权限系统的基本逻辑流程:

  • 1、用户发起操作请求时,根据url匹配到相应的试图函数处理(返回相关信息)
  • 2、在给用户返回信息之前,首先验证该用户是否有权限查看所请求的信息(装饰器)
  • 3、装饰器函数中,通过监测用户http请求的url、method和参数来确定权限
  • 4、若验证通过,返回查询信息(执行被装饰器装饰的函数)。若验证不通过,返回 403 页面

1、在每个给前端返回信息的views函数上添加装饰器,

from permissions import check_permission #导入方法

@check_permission #向前段页面返回客户信息时,先执行装饰器方法,验证是否有权限
def customer(request):
,,,
@check_permission     
def customer_info(request,customer_id):
  ,,,

2、model中添加规则(数据库中添加权限纪录)

class UserProfile(models.Model):
user = models.OneToOneField(User)
name = models.CharField(u"姓名",max_length=32)
def __unicode__(self):
return self.name
class Meta:
verbose_name_plural = u'用户信息' permissions = ( #可以在任一表中添加
('views_customer_list','显示列表信息'),
('views_customer_info','显示每条详细信息'),
('edit_views_culstomer_info','修改详细信息'),
)

修改了models.py文件后,需要同步到数据库。

sudo python manage.py makemigrations

sudo python manage.py migrate

3、定义权限匹配方法

appname/permission.py

#!_*_ coding:utf-8 _*_

from django.core.urlresolvers import resolve
from django.shortcuts import render,redirect perm_dic ={
'views_customer_list':['customer_list','GET',[]], #请求到达时,先匹配url,然后匹配请求方法,最后匹配参数,若都通过,则付给views_customer_list的权限
'views_customer_info':['customer_info','GET',[]],
'edit_views_customer_info':['customer_info','POST',['test']] #这里['test']可以随便填写
} #不确定函数参数时,用 *args,**kwargs
def perm_check(*args,**kwargs):
request = args[0]
#反向映射,将客户端请求的url转换为url别名,request.path_info为请求的完整url
url_resovle_obj = resolve(request.path_info)
#获取url别名
current_url_namespace = url_resovle_obj.url_name
#设置标示符,要匹配(循环)好多层时,可以先设置一个标示符,这里默认不匹配
matched_flag = False
matched_perm_key = None
#如果存在url别名(url中必须有别名)
if current_url_namespace is not None:
#循环别名字典,取key值,即别名
for perm_key in perm_dic:
#字典里所有的值
perm_val = perm_dic[perm_key]
#格式必须为3个参数
if len(perm_val) == 3:
url_namespace,request_method,request_args = perm_val
#先判断url是否匹配
if url_namespace == current_url_namespace:
#再判断请求方法是否匹配
if request.method == request_method:
#如果别名字典(perm_dic)中参数[]为空,则直匹配前两者即可
if not request_args:
#匹配成功
matched_flag = True
#将别名(字典key)付值给matched_perm_key
matched_perm_key = perm_key
#已匹配成功,退出循环
break
else: #字典中如果有参数,(参数可能有多个)
#循环所有的参数
for request_arg in request_args:
#反射获取客户端请求的方法,这样就不用判断是get还是post了
request_method_func = getattr(request,request_method)
#如果请求的每个参数都能匹配成功
if request_method_func.get(request_arg) is not None:
matched_flag = True #匹配成功
else:
matched_flag = False
break
#如果全都匹配成功
if matched_flag == True:
matched_perm_key = perm_key
break
else:
#如果没有进行权限匹配,则默认通过
return True
#如果权限匹配全部通过
if matched_flag == True:
#stu_crm.views_customer_list
perm_str = "stu_crm.%s" %(matched_perm_key)
#.has_perm()方法django自带,其参数为appname+auth_permission表中的codename字段,如果有此权限,则返回True
if request.user.has_perm(perm_str):
return True
else:
return False
else:
print("\033[41;1m ----- no matched permission ----\033[0m") def check_permission(func):
def wrapper(*args,**kwargs):
#如果没权限
if not perm_check(*args,**kwargs):
#args[0]即为request
return render(args[0],'stu_crm/403.html')
return func(*args,**kwargs)
return wrapper

4、修改customer.html,将固定的url用别名代替

<td><a href="{% url 'customer_info' customer.id %}">{{ customer.id }}</a></td>

5、修改url转发规则,加入别名

appname/urls.py

urlpatterns = [
url(r'^$',views.dashboard),
url(r'^customer/$',views.customer,name='customer_list'),
url(r'^customer/(\d+)/$',views.customer_info,name='customer_info'), #必须添加url别名
]

6、定义403页面。

templates/403.html

设置完毕后,使用超级用户登陆admin后台,在user中对每个普通用户设置权限。每添加一条权限,在表 'auth_user_user_permissions' 中就会记录一条。

注:应首先使用超级用户将普通用户的'Staff status'选项选中,以便首先允许其登陆。

Django中的权限系统的更多相关文章

  1. Django中用户权限模块

    Django中用户权限模块 1 auth模块 auth模块是Django提供的标准权限管理系统,可以提供用户身份认证, 用户组和权限管理. auth可以和admin模块配合使用, 快速建立网站的管理系 ...

  2. django 中的路由系统(url)

    路由系统 根据Django约定,一个WSGI应用里最核心的部件有两个:路由表和视图.Django框架 的核心功能就是路由:根据HTTP请求中的URL,查找路由表,将HTTP请求分发到 不同的视图去处理 ...

  3. Django 中使用权限认证

    权限认证 权限概念 """ 在实际开发中,项目中都有后台运营站点,运营站点里面会存在多个管理员, 那么不同的管理员会具备不同的任务和能力,那么要实现这样的管理员功能,那么 ...

  4. Django中的路由系统:urls

    Django的路由系统 URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表. 你就是以这种方式告诉Django,对于这个URL调用 ...

  5. django中的权限控制(form增删改)

    Django默认提供了权限控制,但只能对使用了其自带的登录认证的用户进行权限控制,说白了就是只能对存储在auth_user表中的用户进行权限控制,但不能对未登录过的用户进行权限控制.但如果通过集成LD ...

  6. django中admin路由系统工作原理

    一.如图所示 from django.contrib import admin from . import models class zhangsan(admin.ModelAdmin): list_ ...

  7. Django内置权限扩展案例

    当Django的内置权限无法满足需求的时候就自己扩展吧~ 背景介绍 overmind项目使用了Django内置的权限系统,Django内置权限系统基于model层做控制,新的model创建后会默认新建 ...

  8. Django进阶(路由系统、中间件、缓存、Cookie和Session、Ajax发送数据

    路由系统 1.每个路由规则对应一个view中的函数 url(r'^index/(\d*)', views.index), url(r'^manage/(?P<name>\w*)/(?P&l ...

  9. Django入门2:路由系统

    1.单一路由对应 url(r'^index/', views.index), # FBV url(r'^home/', views.Home.as_view()), # CBV 2.基于正则的路由 u ...

随机推荐

  1. IOS 成员变量,全局变量,局部变量定义,static与extern的区别

    IOS 成员变量,全局变量,局部变量定义,static与extern的区别 1,先说定义 1)成员变量定义:生存与该类的生命周期,变量存活周期跟你定义的该类实体对象一样:作用域是整个实体对象:可以在h ...

  2. POJ 1118 Lining Up

    枚举,排序. 先将所有点按双关键字排序,然后枚举线的顶点$P$,剩余的点以$P$为中心进行极角排序,可以取个$gcd$,这样一样的点就排在一起了,然后统计一下更新答案. #pragma comment ...

  3. USACO 3.3 TEXT Eulerian Tour中的Cows on Parade一点理解

    Cows on Parade Farmer John has two types of cows: black Angus and white Jerseys. While marching 19 o ...

  4. Firewalld防火墙

    Firewalld服务是红帽RHEL7系统中默认的防火墙管理工具,特点是拥有运行时配置与永久配置选项且能够支持动态更新以及"zone"的区域功能概念,使用图形化工具firewall ...

  5. 手机端rem自适应布局实例

    首先要书写核心js代码,控制住页面的初始大小:我是以750px(即iPhone6)的标准,设置font-size:100px:<script>        (function (doc, ...

  6. 《JavaScript网页经典特效300例》

    <JavaScript网页经典特效300例> 基础篇 进阶篇 高级篇

  7. PAT乙级1001. 害死人不偿命的(3n+1)猜想 (15)

    卡拉兹(Callatz)猜想: 对任何一个自然数n,如果它是偶数,那么把它砍掉一半:如果它是奇数,那么把(3n+1)砍掉一半.这样一直反复砍下去,最后一定在某一步得到n=1.卡拉兹在1950年的世界数 ...

  8. Java NIO Channel之FileChannel [ 转载 ]

    Java NIO Channel之FileChannel [ 转载 ] @author zachary.guo 对于文件 I/O,最强大之处在于异步 I/O(asynchronous I/O),它允许 ...

  9. swift 中Value Type VS Class Type

    ios 中Value Type 和 Class Type 有哪些异同点,这个问题是在微信的公共帐号中看到的,觉得挺有意思,这里梳理一下. 1.swift 中为什么要设置值类型? 值类型在参数传递.赋值 ...

  10. SQL 分组排序、CASE...WHEN...、是否为空 查询

    select  Id,CustomerCode,CustomerName,CreateId,CreateName,Phone,StatusName,(case when phone is not nu ...