钩子函数,modelfrom组件,django中间件

钩子函数

需求:以上我们写的form组件中写一个注册功能,现在要求判断用户是否已经存在
提供了两个自定义的校验方式;
	局部钩子:校验单个字段
    全局钩子:校验多个字段

1.局部钩子:校验单个字段

class MyForm(forms.Form):
    '''属于第一层校验'''
    # 用户名最长8个字符,最短3个字符
    name = forms.CharField(max_length=8, min_length=3, label='用户名')
    pwd = forms.IntegerField(label='密码')
     confirm_pwd = forms.IntegerField(label='确认密码')
    # 用户年龄最大150,最小0岁
    age = forms.IntegerField()
    # 邮箱必须符合邮箱格式
    email = forms.EmailField()
    
    '''这个属于第二层的校验,第一层校验通过之后才会执行这层校验'''
    # 校验用户名是否存在
    def clean_name(self):
        # 勾子函数会等上面的校验通过以后才会执行,相当于最后一层校验
        name = self.cleand_data.get('name')
        res = models.User.objects.filter(name=name).first()
        if res:
            # 给前端一个消息,这个消息鬼属于name框,出错了提示会放在name框中
            return self.add_error('name', '用户名已存在')
        # 没有问题的话,记得拿了什么东西要返回回去,“把人家的东西勾来了,记得给放回去”
        return name

image

2.全局钩子:校验多个字段

# 校验两次密码是否一致
# clean这个字段就是校验多个字段的,固定的
def clean(self):
    pwd = self.cleand_data.get('pwd')
    confirm_pwd = self.cleand_data.get('confirm_pwd')
    if not pwd == confirm_pwd:
    	return self.add_error('confirm_pwd','两次密码不一致')
    return self.cleand_data

modelfrom组件

modelform是form的优化版本 使用更简单 功能更强大
class MyModelForm(forms.ModelForm):
    class Meta:
        # 先写一下对哪个表做校验
        model = models.User
        # 双下all 代表着所有的字段
        fields = '__all__'
    def ab_mf_func(request):
        modelform_obj = MyModelForm()
        if request.method == 'POST':
            modelform_obj = MyModelForm(request.POST,instance=User_obj)
            if modelform_obj.is_valid():
                modelform_obj.save()  
            else:
                print(modelform_obj.errors)
        return render(request, 'modelFormPage.html', locals())

django中间件

django默认有七个中间件 并且还支持用户自定义中间件
中间件主要可以用于:网站访问频率的校验 用户权限的校验等全局类型的功能需求
  
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',
]
如何自定义中间件
	1.创建存储自定义中间件代码的py文件或者目录(如果中间件很多)
	2.参考自带中间件的代码编写类并继承
 	3.在类中编写五个可以自定义的方法
    4.一定在配置文件中注册中间件才可以生效
# 需要掌握的:
1.process_request
	(1).请求来的时候会从上往下依次经过每一个注册了的中间件里面的该方法 如果没有则直接跳过
	(2).如果该方法自己返回了HttpResponse对象那么不再往后执行而是直接原路返回
2.process_response
	(1).响应走的时候会从下往上依次经过每一个注册了的中间件里面的该方法 如果没有则直接跳过
	(2).该方法有两个先request和response 形参response指代的就是后端想要返回给前端浏览器的数据 该方法必须返回该形参 也可以替换
	'''如果在执行process_request方法的时候直接返回了HttpResponse对象那么会原路返回执行process_response 不是执行所有'''

	

django中间件三个了解的方法

1.process_view
	路由匹配成功之后执行视图函数/类之前自动触发(顺序同process_request)
2.process_exception
	视图函数/类执行报错自动触发(顺序同process_response)
3.process_template_response
	视图函数/类返回的HttpResponse对象含有render并且对应一个方法的时候自动触发(顺序同process_response)

基于django中间件的功能设计

将各个功能制作成配置文件的字符串形式
	如果想拥有该功能就编写对应的字符串
	如果不想有该功能则注释掉对应的字符串
 
补充知识	
	如果利用字符串导入模块
import importlib
s1 = 'bbb.b'  # aaa.bbb.ccc.b
res = importlib.import_module(s1)  # from aaa.bbb.ccc import b
print(res)  # <module 'bbb.b' from 'D:\\pythonProject03\\djangomiddle\\bbb\\b.py'>
'''注意字符串的结尾最小单位只能是py文件 不能是py文件里面的变量名'''
思考django中间件是如何处理的(最小单位是类名)


需求分析
	模拟编写一个消息通知功能(微信、qq、邮箱)
 
方式1:基于函数封装的版本
	没有眼前一亮的感觉 很一般
方式2:基于django中间件的功能设计
 	眼前一亮 回味无穷

image