• 【钩子函数和cookie与session简介】


    forms钩子函数

    钩子函数的含义其实就是在程序的执行过程中穿插额外的逻辑

    校验用户名是否已存在
    钩子函数之局部钩子(校验单个字段)

    校验密码和确认密码是否一致
    钩子函数之全局钩子(校验多个字段)

    ‘’‘钩子函数是数据经过了第一层校验,即通过了字段设置的校验之后才会执行’‘’

    eg:
    from django import forms
    class Froms(forms.Form):
    username = forms.CharField(max_length=32) # 最大长度32
    password = forms.CharField(min_length=8) # 密码最短八位
    password_again = forms.CharField(min_length=8) # 密码最短八位

    局部钩子:

    校验用户名是否已存在(一次性只能勾一个人)

    
      def clean_username(self):
          # 1.获取用户名
          username = self.cleaned_data.get('username')
          # 2.判断用户名是否已存在
          user_obj = models.User.objects.all()
          if user_obj:
              # 3.设置提示信息
              self.add_error('username','用户名已存在')
          # 4.返回用户名
          return username
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    全局钩子:

    校验密码与确认密码是否一致(一次性可以勾多个人)

     def clean(self):
         # 1.获取数据
         password = self.cleaned_data.get('password')
         password_again = self.cleaned_data.get('password_again')
         # 2.判断两次输入密码是否相同
         if password != password_again:
             # 3.设置提示信息
             self.add_error('password_again','两次密码不一致')
         # 4.返回整个数据
         return self.cleaned_data
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    forms组件字段参数

    参数作用
    min_length最小长度
    max_length最大长度
    label字段名称
    error_messages错误提示
    min_value最小值
    max_value最大值
    initial默认值
    validators正则校验器
    widget控制渲染出来的标签各项属性
    choices选择类型的标签内部对应关系

    正则匹配的使用

    	# 先导入正则模块
        from django.core.validators import RegexValidator
          phone = forms.CharField(
                validators=[
                            RegexValidator(r'^[0-9]+$', '请输入数字'),
                            RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],
            )  # validators里面写正则表达式
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    widget渲染标签

    password = CharField(widget=forms.widgets.PasswordInput(attrs={'class':'form-control'})  # type=’password,class='form-control'
    	'''
    	语法模板:
    	forms.widgets.控制type的类型(attrs=控制各项属性:class id ...)
    	'''   
    
    • 1
    • 2
    • 3
    • 4
    • 5

    choices使用

    hobby = forms.MultipleChoiceField(
            choices=((1, "篮球"), (2, "足球"), (3, "排球")),
        )
        ```
    ### 数据库拿数据
    ```python
    def __init__(self, *args, **kwargs):
            super(MyForm,self).__init__(*args, **kwargs)
            self.fields['hobby'].choices = models.Classes.objects.all().values_list('id','caption')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    forms组件字段类型

    字段类型功能
    CharField字符串框
    PasswordInput密码框
    CheckboxInput单选框
    Select单选下拉框
    SelectMultiple多选下拉框
    CheckboxSelectMultiple多选框
    DecimalFielddecimal类型数据

    forms组件源码分析

    看源码可以提升编程能力(CBV源码)
    也可以从中获取出更多的使用方式(JsonResponse)

    def is_valid(self):
        return self.is_bound and not self.errors
    
    ### 查看类源码发现只要给类传参self.is_bound肯定是True
    
    @property
    def errors(self):
       	if self._errors is None:
           self.full_clean()
        return self._errors
    # 查看了源码发现self._errors初始化就是None 所以肯定走full_clean方法
    
    # 查看源码发现校验数据的整个过程内部都有异常处理机制
    from django.core.exceptions import ValidationError
    raise ValidationError('用户名不存在')
    # 当我们主动抛异常后,程序不会报错,因为源码已经把异常处理掉了
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    ModelForm简介

    我们写models类和写forms类会发现,两个类出奇的像,等于说一个类写了两遍,能不能有一种方法,把这两个类的功能放到一个类里面实现?这就是ModelForm(基于forms组件)

    class MyUser(forms.ModelForm):
        # 固定写法,Meta类
        class Meta:
            models.User  # 指定关联的表
            fields = '__all__'  # 所有的字段全部生成对应的forms字段
            labels = {
                'usernae':'用户名',
                'password':'密码',
            }
            widgets = {
                'name':forms.widgets.TextInput(attrs={'class':'from_control'}),
                'password':forms.widgets.PasswordInput(attrs={'class':'from_control'})
            }
    
    def reg(request):
        form_obj = MyUser()
        if request.method == 'POST':
            form_obj = MyUser(request.POST)
            if form_obj.is_valid():
                form_obj.save()  # 新增数据到数据库 相当于create
                edit_obj = models.User.objects.filter(pk=2).first()
                form_obj = MyUser(request.POST,instance=edit_obj)
                form_obj.save()  # 修改数据,相当于update
        return render(request,'register.html',locals())
    
    '''
    save()方法:
    	如果调用save()的对象中传了instance,就是修改数据
    	没有传instance,就是保存数据
    '''
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    cookie与session简介

    cookie简介

    早期的互联网应用程序都是不保存用户状态的,所有人发送请求返回的都是相同的页面
    现如今几乎所有的应用程序都可以保存用户状态!!!>>>:如何实现的???
    HTTP协议四大特性之一:无状态
    让服务端知道你是谁的方式很单一>>>:携带用户名和密码(身份标识)
    每次操作之前都需要输入用户名和密码
    当你成功登录之后浏览器会在本地帮你保存用户名和密码
    每次操作浏览器自动发送用户名和密码
    cookie本质
    指代服务端让客户端保存的数据(存储在客户端上与用户信息相关的数据)
    ‘’‘简单的记忆:cookie就是存在客户端的东西’‘’

    session简介

    早期的cookie是直接存储的用户明文相关信息 不安全
    用户登录成功之后 服务端生成一个随机字符串 返回给客户端保存
    
    • 1
    • 2

    之后客户端每次发请求携带该随机字符串 服务端获取之后比对后台数据
    eg:
    服务端
    随机字符串1 用户数据1
    随机字符串2 用户数据2
    随机字符串3 用户数据3
    客户端
    随机字符串1、随机字符串2、随机字符串3
    session本质
    指代服务端保存的跟用户信息相关的数据
    ‘’‘简单的记忆:session就是存在服务端的东西’‘’
    “”"
    1.session的工作必须依赖于cookie
    2.客户端也有权拒绝保存数据
    “”"
    ps:针对身份标识问题有很多方式 cookie和session是最基本的
    token、jwt…

    django操作cookie

    视图函数返回值

    return HttpResonse()		
    return render()
    return redirect()
    ...
    
    • 1
    • 2
    • 3
    • 4

    不直接返回对象 而是先用变量名指代 然后操作对象方法

    res = HttpResonse()
    return res
    res = render()
    return res
    res = redirect()
    return res

    基本使用

    res.set_cookie()  # 设置
     res.COOKIE.get()  # 获取
    cookie完成登录校验
    
    • 1
    • 2
    • 3

    后端代码

    def login(request,url=None):
        form_obj = MyUser()
        if request.method == 'POST':
            username = request.POST.get('username')
            password = request.POST.get('password')
            user_obj = models.User.objects.filter(username=username,password=password).first()
            res = redirect(url)
            if user_obj:  # 如果验证通过
                res.set_cookie('username',username)  # 设置cookie
                return res
            return HttpResponse('用户名或密码错误')
        return render(request,'login.html',locals())
    
    
    from utils.mypage import is_login
    
    def home(request):
        @is_login(request.COOKIES.get('username'),'/home/')
        def login_ok():
            return HttpResponse('欢迎来到home')
        return login_ok()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    登录装饰器

    from django.shortcuts import redirect
    def is_login(cookie,url):
        def outer(func_name):
            def inner(*args,**kwargs):
                if cookie:
                    res = func_name(*args,**kwargs)
                    return res
                else:
                    return redirect(f'/login/{url}/')
            return inner
        return outer
        ```
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  • 相关阅读:
    指标计算实践
    CDISC SDTM IG 3.3 版本相比于 3.2版本的变化 (上)
    多线程获取官方汇率
    抓包神器TCPDUMP的分析总结-涵盖各大使用场景、高级用法
    计算机毕业设计(附源码)python长途汽车订票系统
    【面试题】Vue 基础之Vuex(五)
    负载均衡原理
    react-intl国际化在项目中的使用
    docker创建elasticsearch、elasticsearch-head部署及简单操作
    世界芯片公司
  • 原文地址:https://blog.csdn.net/Ban_a/article/details/124936507