CSRF装饰器与基于中间件注册思想编写项目与auth认证模块
- CSRF相关装饰器
- 通过字符串导入模块
- 基于中间件注册思想编写项目
- auth认证模块
- auth模块方法
- auth扩展表字段
CSRF相关装饰器
关于CSRF有两个装饰器:
from django.views.decorators.csrf import csrf_exempt, csrf_protect
- csrf_exempt:用于忽略CSRF校验的装饰器
- csrf_protect:用于开启CSRF校验的装饰器
csrf_exempt
这个一般用于使用了CSRF的中间件的时候,因为使用了CSRF中间件相当于给所有视图函数开启了CSRF校验,这个装饰器就是为了给某个视图函数忽略CSRF校验用的。
csrf_protect
这个一般用于没有使用CSRF的中间件的时候,因为所有视图函数都没有开启了CSRF校验,这个装饰器就是为了给某个视图函数开启CSRF校验用的。
针对FBV使用
两个装饰器都可以直接在函数上方添加
@csrf_exempt
def index(request):
return HttpResponse()
针对CBV使用
csrf_protect:三种CBV添加装饰器的方式都可以
csrf_exempt:只有给重写的dispatch方法装饰可以生效
class MyView(views.View):
def get(self, request):
return HttpResponse()
@method_decorator(csrf_exempt)
def dispatch(self, request, *args, **kwargs):
return super().dispatch(request, *args, **kwargs)
通过字符串导入模块
通过中间件的配置文件看到:
很显然这些都是一个个模块,这种通过字符串导入模块的方式是因为使用了importlib模块,这个模块可以把字符串的路径导入。
导入模块
import importlib
使用:
module_path = 'aaa.c'
importlib.import_module(module_path)
等价于常规导入方式:
from aaa import c
这个模块有一个缺点:最小导入单位是模块文件级别,也就是无法导入模块文件名称空间中的名称。既无法单独导入py文件中的变量名、函数名、类名等。
基于中间件注册思想编写项目
我们编写完自定义中间件后需要去配置文件中进行注册,这个功能就会自动添加到项目中,那么我们该如果实现这种相同效果呢?
现在想要实现一个功能:不动运行文件,只创建一个方法,并把这个方法配置在配置文件中,就可以执行内部代码。
我们已发送信息模拟。
首先创建如下文件:
email.py:
class Email:
def send(self, msg):
print('邮箱发送了:%s' % msg)
phone.py:
class Phone:
def send(self, msg):
print('短信发送了:%s' % msg)
qq.py:
class QQ:
def send(self, msg):
print('QQ发送了:%s' % msg)
settings.py:
SETTINGS = [
'aaa.email.Email',
'aaa.phone.Phone',
'aaa.qq.QQ',
]
start.py:
import importlib
from settings import SETTINGS
def send_all(msg):
# 1.循环配置文件中的路径
for str_path in SETTINGS:
# 2.切割路径,比如'aaa.qq.QQ'切割成'aaa.qq'与'QQ'
module_name, str_class_name = str_path.rsplit('.', maxsplit=1)
# 3.导入模块
module = importlib.import_module(module_name)
# 4.利用反射获取模块内名称空间的名称
class_name = getattr(module, str_class_name)
# 5.实例化
obj = class_name()
# 6.调用对象里面的方法
obj.send(msg)
if __name__ == '__main__':
send_all('666')
auth认证模块
django给我们提供了一个可以快速完成用户相关功能的模块,那就是auth认证模块,包含用户创建、认证、编辑等。
也提供了一张用户表,这张表是在我们执行数据库迁移命令之后默认产生的:auth_user表,里面记录了用户的各种信息。
创建django自带的路由url(r'^admin/', admin.site.urls)就是参考这张表的信息认证的。
其中is_superuser字段就是判断这个用户是否是管理员用的,我们可以自己创建一个管理员。
进入run manage.py task终端,输入:
createsuperuser
然后按照提示信息输入就可以了,这时候我们就可以访问django自带的admin路由去登录了。
随便一提,auth_user中的密码是经过加密处理后保存的,有更高的安全性。
auth模块方法
要使用auth模块首先要导入:
from django.contrib import auth # 主要模块
from django.contrib.auth.models import User # 用户表
创建普通用户:根据auth_user表添加,username字段必填
User.objects.create_user(username=,)
创建管理员用户:根据auth_user表添加,username、password、email字段必填
User.objects.create_superuser(username=,password=,email=)
验证用户名和密码是否正确:返回一个用户对象,可以获取其他字段信息,用户名和密码错误返回None。
user_obj = auth.authenticate(request,username=username,password=password)
保存用户登录状态:自动帮你操作session相关
auth.login(request, user_obj)
获取当前用户对象:返回当前登录的用户对象,没有登录则返回AnonymousUser对象,里面没有信息
user_obj = request.user
判断当前用户是否登录:返回布尔值
request.user.is_authenticated()
比对密码是否与当前登录用户相同:返回布尔值
request.user.check_password('password')
修改密码:需要保存
request.user.set_password('new_password')
request.user.save() # 同步到数据库中
注销当前已登录用户:即删除seesion
auth.logout(request)
校验登录装饰器:
导入:
from django.contrib.auth.decorators import login_required
局部配置:login_url即未登录用户跳转的路由地址
@login_required(login_url='/login/')
全局配置:默认跳转到/accounts/login/
@login_required
可以在settings.py配置文件中配置全局:
LOGIN_URL = '/login/' # 在配置文件中添加路由地址
auth扩展表字段
如果想要在原有的auth_user表上扩展表字段,有两种方式:
方式一:编写一对一表关系,自己创建一张表,与auth_user建立一对一关系即可。
方式二:自己在模型层创建一个类去继承auth的用户类。
from django.contrib.auth.models import AbstractUser
class MyUser(AbstractUser):
# 编写AbstractUser类中没有的字段,不能冲突
phone = models.BigIntegerField()
addr = models.CharField(max_length=32)
编写完类后,还需要去settings.py配置文件里添加配置:app01是我的应用名,并且添加配置不需要写models路径
AUTH_USER_MODEL = 'app01.MyUser'
补充:
- 类继承之后,需要重新执行数据库迁移命令,并且库里面是第一次操作迁移命令才可以,也就是auth_user表还没有被创建之前才能生效。
- auth模块所有的方法都可以直接在自定义模型类上面使用,因为是继承关系。