ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Forms组件、勾子函数

2022-09-08 23:34:11  阅读:281  来源: 互联网

标签:forms obj name form 勾子 request 校验 Forms 组件


目录

Forms组件

前戏

前戏:编写用户登录功能并且校验数据返回提示信息(form表单)

写一个注册功能
1.获取用户名和密码 利用form表单提交数据
2.在后端判断用户名和密码是否符合一定的条件
	3.用户名不能是Jason
	4.密码不能为123

# 符合条件需要你将提示信息动态的展示到前端页面

前端

<form action="" method="post">
    <p>username:
        <input type="text" name="username">
        {# 行内标签 get请求为空 不占任何标签    post请求有值 就可以点到对应的数据    #}
        <span style="color: red">{{ data_dict.username }}</span>
    </p>
    <p>password:
        <input type="text" name="password">
        <span style="color: red">{{ data_dict.password }}</span>
    </p>
    <input type="submit" class="btn btn-info">
</form>

后端

def ab_form(request):
    # 不能使用ajax,那么它就是影响的整个页面
    data_dict = {'username': '', 'password': ''}
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')
        if username == 'jason':
            data_dict['username'] = 'jason是不能使用的'
        if password == '123':
            data_dict['password'] = '密码不能设置这么简单的'
    return render(request, 'ab_form.html', locals())

image

form组件

1.数据校验
    	支持提前设置各种校验规则 之后自动校验
2.渲染页面
    	支持直接渲染获取用户数据的各种标签
3.展示信息
    	支持针对不同的校验失败展示不同的提示

form组件基本使用

1.form类型创建

首先需要导入模块:from django import forms
然后创建类

from django import forms

class MyForm(forms.Form):
    # 用户名最长8个字符,最短3个字符
    name = forms.CharField(max_length=8, min_length=3)
    # 用户年龄最大150,最小0岁
    age = forms.IntegerField(max_value=150, min_value=0)
    # 邮箱必须符合邮箱格式
    email = forms.EmailField()

2.校验数据

测试环境俩种方式

1.测试环境的准备 可以自己拷贝代码准备
2.其实在pycharm左下角已经帮你准备一个测试环境  "python console"
from app01 import views
# 1 将带校验的数据组织成字典的形式传入即可
form_obj = views.MyForm({'username':'jason','password':'123','email':'123'})

# 2 判断数据是否合法
注意该方法只有在所有的数据全部合法的情况下才会返回True
form_obj.is_valid()
False

# 3 查看所有校验通过的数据
form_obj.cleaned_data
{'username': 'jason', 'password': '123'}

# 4 查看所有不符合校验规则以及不符合的原因
form_obj.errors
{
  'email': ['Enter a valid email address.']
}

image
校验数据只校验类中出现的字段 多穿不影响 多穿的字段直接忽略

form_obj = views.MyForm({'username':'jason','password':'123','email':'123@qq.com','hobby':'study'})
form_obj.is_valid()
True

校验数据 默认情况下 类里面所有的字段都必须传值

form_obj = views.MyForm({'username':'jason','password':'123'})
form_obj.is_valid()

False

image

也就意味着校验数据的时候 默认情况下数据可以多传但是绝不可能少传

3.渲染标签功能(类中以外的所有标签都不会自动渲染 需要自己编写)

1.方式1(封装程度高 扩展性差)
{{ form_obj.as_p }}
{{ form_obj.as_table }}
{{ form_obj.as_ul }}

image
这种方法的缺点是封装程度太高了,什么都是人家渲染出来的,并且带了label和p标签,如果不想要呢,扩展性差
image
渲染成无序列表形式
image

2.方式2(封装程度低 扩展性好 编写困难)
{{ form_obj.name.label }}
{{ form_obj.name }}
{{ form_obj.age.label }}
{{ form_obj.age }}
{{ form_obj.email.label }}
{{ form_obj.email }}

image

3.方式3(推荐使用)
{% for form in form_obj %}
<p>{{ form.label }}{{ form }}</p>
{% endfor %}

image
只渲染类里写的字段,如果要使用按钮之类的需要自己写,类中意外的字段都不会自动渲染

4.展示提示信息

1.form表单如何取消浏览器自动添加的数据校验功能
<form action="" method="post" novalidate>
{#    novalidate不做任何校验#}
    {% for form in form_obj %}
    <p>{{ form.label }}{{ form }}</p>
    <input type="submit" value="提交">
{% endfor %}
</form>
2.form.errors生成的是列表的格式

image

3.错误信息展示
def func(request):
    # 产生一个空对象
    form_obj = MyForm()
    if request.method == 'POST':
        # 获取用户上传的数据,现在我们不需要用我们以前的那种笨拙的办法了(get)
        # request.POST它是一个dict,将它看作是一个字典
        # 产生了一个新的对象
        form_obj = MyForm(request.POST)
        # 判断一下我们传入的是否都是正确的
        if form_obj.is_valid():
            print(form_obj.cleaned_data)
    return render(request, 'func.html', locals())
<form action="" method="post" novalidate>
{#    novalidate不做任何校验#}
    {% for form in form_obj %}
    <p>
        {{ form.label }}{{ form }}
        <span style="color: red">{{ form.errors.0 }}</span>
    </p>

{% endfor %}
    <input type="submit" value="提交">
</form>

image

4.错误信息修改为中文
name = forms.CharField(max_length=8, min_length=3, label='用户名',
                           error_messages={
                               'max_length':'用户名最多只能是8个字符',
                               'min_length':'用户名最少只能是3个字符',
                               'required':'用户名不能为空'
                           }
                           )

image
可以以直接修改这里,将整个底层结构展示为中文,在settings.py里
image
image
image

5.form中重要的字段参数

max_length、min_length
max_value、min_value

label				字段注释
error_messages			错误提示
required			是否为空
widget				标签类型、标签属性
initial				默认值
validators			正则校验

钩子函数

需求:以上我们写的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()
    '''属于第二层校验,第一层校验通过以后才会执行这层校验'''
    # 1.校验用户名是否已经存在
    def clean_name(self):
        # 勾子函数会等上面的校验通过以后才会执行,相当于最后一层校验
        # 第二层校验的话cleaned_data里面肯定会有值,因为第一层校验已经通过了
        name = self.cleaned_data.get('name')
        res = models.User.objects.filter(name=name).first()
        if res:
            # 给前端一个消息,这个消息鬼属于name框,出错了提示会放在name框中
            return self.add_error('name', '用户名已存在')
        # 没有问题的话,记得拿了什么东西要返回回去,“把人家的东西勾来了,记得给放回去”
        return name
def func(request):
    # 产生一个空对象
    form_obj = MyForm()
    if request.method == 'POST':
        # 获取用户上传的数据,现在我们不需要用我们以前的那种笨拙的办法了(get)
        # request.POST它是一个dict,将它看作是一个字典
        # 产生了一个新的对象
        form_obj = MyForm(request.POST)
        # 判断一下我们传入的是否都是正确的
        if form_obj.is_valid():
            # 保存数据信息
            res = form_obj.cleaned_data
            # 要把确认密码移除调,它不属于我们数据库中,只是在校验中使用过
            res.pop('confirm_owd')
            models.User.objects.create(**res)
    return render(request, 'func.html', locals())

image

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


标签:forms,obj,name,form,勾子,request,校验,Forms,组件
来源: https://www.cnblogs.com/zxr1002/p/16671184.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有