Django源码剖析
Django配置文件
# django真正的配置文件
from django.conf import global_settings
'''
settings.py只是django暴露给用户供用户自定义的配置文件
global_settings.py是django默认的全局配置文件
'''
# 如果用户在settings.py中自定义的配置则使用用户自定义的,否则使用默认的
# 暴露给用户的配置文件中有的配置,全局配置文件肯定有,暴露给用户的配置文件中没有的配置,全局配置文件也有
# 在django中导入配置文件正确的方式
from django.conf import settings
Django配置文件源码剖析
from django.conf import settings
# 通过源码,可以发现这个settings是一个类
os.environ:内置的全局字典
settings_module = os.environ.get(ENVIRONMENT_VARIABLE) # 获取暴露给用户的配置文件的字符串路径
self._wrapped = Settings(settings_module) # 把路径字符串传给Settings类实例化
class Settings(object):
def __init__(self, settings_module):
for setting in dir(global_settings): # 获取全局配置文件的配置名字
if setting.isupper(): # 校验变量名是否是纯大写
setattr(self, setting, getattr(global_settings, setting)) # 通过反射获取系统配置文件的所有的大写变量名和对应的值赋值给settings对象
self.SETTINGS_MODULE = settings_module
mod = importlib.import_module(self.SETTINGS_MODULE) # 通过字符串路径导入模块
self._explicit_settings = set()
for setting in dir(mod): #循环获取用户自定义的配置文件的变量名
if setting.isupper():
setting_value = getattr(mod, setting) # 获取变量名对应的值
if (setting in tuple_settings and
not isinstance(setting_value, (list, tuple))):
raise ImproperlyConfigured("The %s setting must be a list or a tuple. " % setting)
setattr(self, setting, setting_value) # 把变量名和变量值添加到对象里面
self._explicit_settings.add(setting)
# 用户在settings.py中自定义的配置则使用用户自定义的,否则使用默认的配置原理:
在Settings类中,执行了两次加载配置的操作,先加载global_settings的配置,然后加载用户项目中的settings,如果用户自定义了配置,则global_settings的配置会被替换
基于settings源码编程
# 基于settings源码编程,原理就是设置好默认的参数,暴露给用户一个可以修改的文件,先加载系统默认参数并赋值给settings对象,再加载用户自定义参数,如果用户自定义了参数则把系统默认参数替换掉
权限管理简介
# web领域的权限就是url
'''
本质就是在用户访问资源时,获取该用户的访问权限,如果有权限,则允许访问该url,如果没有权限则拒绝访问
'''
# 权限设计
用户表
id name pwd
1 a aaa
2 b bbb
3 c ccc
权限表
id permission
1 添加数据
2 修改数据
3 删除数据
用户_权限关系表
user_id permission_id
1 1
1 2
2 3
3 1
'''
缺点:
用户多了第三张表关系非常复杂
'''
RBAC
用户表
id name pwd
1 a aaa
2 b bbb
3 c ccc
角色表
id role
1 CEO
2 保安
3 保洁
权限表
id permission
1 添加数据
2 修改数据
3 删除数据
用户_角色关联表
user_id role_id
1 1
2 3
3 2
角色_权限关联表
id role_id permission_id
1 1 1
2 2 2
3 3 3
'''
后续添加权限只需要添加角色即可,无需再去该权限关联表
'''
RBAC实战
# 进行权限校验主要通过中间件实现功能
# 自定义中间件process_request方法,这个方法会在请求来的时候触发,我们在用户登录时获取用户权限,绑定到session中,在process_request方法中进行校验当前访问路径是否有权限,有则允许访问,无则拦截本次访问
# 自定义中间件
from django.utils.deprecation import MiddlewareMixin
import re
from django.http import HttpResponse
class MyPermission(MiddlewareMixin):
def process_request(self,request):
# 定义白名单,不需要权限也可访问
white_url = ['/login/','/register/']
# 1.获取请求地址
target_url = request.path
# 如果访问的url在白名单中,直接放行
re_path = '^%s$'%target_url
for url in white_url:
res = re.search(re_path,url)
if res:
return
# 2.获取session中的权限列表
permission_url = request.session.get('permission_list')
# 3.判断用户是否有权限访问当前url
for url in permission_url:
res = re.search(re_path, url)
if res:
return
return HttpResponse('当前访问地址无权限')
'''
拓展延伸:
1.黑名单
2.校验访问频率
'''
admin配置
# 在注册模型表的时候,可以添加配置
class Userconfig(models.User):
list_display = ['username','password','age'] # 控制展示字段
list_display_links = ['password'] # 控制字段跳转
search_fields = ['username','age'] # 通过搜索框查找对应字段
list_filter = ['username'] # 筛选框 一般填外键名
def patch_init(self,request,queryset): # queryset操作函数
queryset.update(age = F('age')+1)
patch_init.short_description = '批量年龄加一' # 定义功能名字
actions = [patch_init,] # 自定义queryset操作