forms组件

form组件

一、前戏

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

写一个注册功能
1.获取用户名和密码,利用form表单提交数据
2.在后端判断用户名和密码是否符合一定的条件
3.用户名不能是jason,密码不能是123
'''符合条件需要你将提示信息动态的展示到前端页面'''

前端

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

后端

def ab_form_func(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'] = '密码不能是123'
    return render(request, 'ab_form.html', locals())

image

二、form组件

1.主要功能

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

2.form组件基本使用

<1>.form类型创建

首先需要导入模块

from django import forms

然后创建类

from django import forms

class MyForm(forms.Form):
    username = forms.CharField(min_length=3, max_length=8)  # username字段最少三个字符最大八个字符
    age = forms.IntegerField(min_value=0, max_value=200)  # 年龄最小0 最大200
    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_vaild()
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.ccom','hobby':'study'})
form_obj.is_valid()
True

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

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

False

image

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

<3>.渲染标签功能

类中以外的所有标签都不会自动渲染,需要自己编写

方式1(封装程度高,扩展性差 主要用于本地测试)

{{ form_obj.as_p }}
{{ form_obj.as_ul }}
{{ dorm_obj.as_table }}

image

这种方法的缺点是封装程度太高了,什么都是人家渲染出来的,并且带来label和p标签,扩展性差

image

渲染成无序列表形式

image

方式2(封装程度低,扩展性好,编写困难)

{{ form_obj.name.label }}
{{ form_obj.name }}
{{ form_obj.age.label }}
{{ form_obj.age }}
{{ form_obj.email.label }}
{{ form_obj.email }}

image

方式3(推荐使用)

{% for form in form_obj %}
<p>{{ form.label }}{{ form }}</p>
{% endfor %}

image

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

form表单如何取消浏览器自动添加的数据校验功能

<form action="" method="post" novalidate>
{# novalidate不做任何校验 #}
    {% for form in form_obj %}
	<p>{{ form.label }}{{ form }}</p>
	{% endfor %}
</form>

<4>.展示提示信息

后端不同请求返回的forms对象一定要是相同的变量名

后端代码

def ab_forms_func(request):
    # 1.产生一个空对象
    form_obj = MyForm()
    if request.method == 'POST':
        form_obj = MyForm(request.POST)  # request.POST可以看成是一个字典,直接传给forms类校验,字典中无论有多少键值对都没关系,只在乎类中编写的
        if form_obj.is_valid():  # 校验数据是否合法
            print(form_obj.cleaned_data)
		else:
            print(form_obj.errors)
    # 2.将该对象传递给html文件
    return render(request, 'formsPage.html', locals())

前端代码

<form action="" method="post" novalidate>
    {% for form in form_obj %}
    	<p>
         	{{ form.label }}
            {{ form }}
    	</p>
    		<span>{{ form.errors.0 }}</span>
    {% endfor %}
    <input type="sumbit">
</form>

针对错误信息的提示可以修改成各国语言

方式一:自定义内容

给字段对象添加errors_messages参数

username = forms.CharField(min_length=3, max_length=8,label='用户名',
                               error_messages={
                                   'min_length': '用户名最少三个字符',
                                   'max_length': '用户名最多八个字符',
                                   'required': '用户名不能为空'
                               }
                               )

方式二:修改系统语言环境

from django.conf import global_settings
django内部真正的配置文件

我们可以在这里面修改我们想要修改的语言

image

image

image

image

3.form组件参数

min_length			最小字符
max_length			最大字符
min_value			最小值
max_value			最大值
label				字段注释
error_messages		错误提示
validators			正则校验器
initial				默认值
required			是否必填
widget				控制标签的各项属性
	widget = forms.widgets.PasswordInput(attrs={'class': 'form-control', 'username': 'jason'})

三、forms组件校验补充

forms组件针对字段数据的校验,提供了三种类型的校验方式(可以一起使用)

1.直接填写参数

max_length

2.使用正则表达式

from django.core.validators import RegexValidator
 
class MyForm(Form):
    user = fields.CharField(
        validators=[
            RegexValidator(r'^[0-9]+$', '请输入数字'), 
            RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],
    )

3.钩子函数

需求:以后我们写的form组件中写一个注册功能,现在要求判断用户是否已经存在

提供自定义的校验方式
	局部钩子:校验单个字段
    全局钩子:校验多个字段

<1>.局部钩子

class MyForm(forms.Form):
    '''属于第一层校验'''
    username = forms.CharField(min_length=3, max_length=8,label='用户名')
    password = forms.CharField(min_length=3, max_length=8, label='密码')
    confirm_pwd = forms.CharField(min_length=3, max_length=8, label='确认密码')
    	# 钩子函数>>>:每次只校验一个字段数据
    	def clean_username(self):
            username = self.cleaned_data.get('username')
            if username == 'jason':
                self.add_error('username', '用户名jason已存在')
            return username   

<2>.全局钩子

一次可以校验多个字段数据,校验两次密码是否一致

def clean(self):
    password = self.cleaned_data.get('password')
    confirm_pwd = self.cleaned_data.get('confirm_pwd')
    if not password == confirm_pwd:
        self.add_error('confirm_pwd', '两次密码不一致')
    return self.cleaned_data

四.modelfrom组件

我们学习校验性组件的目的,绝大部分是为了数据录入数据库之前的各项审核
forms组件使用的时候需要对照模型类型编写代码,不够方便
forms组件的强化版本,更好用更简单更方便!!!
from django import forms
from app01 import models


class MyModelForm(forms.ModelForm):
    class Meta:
        # 写一下要针对那一个表做校验
        model = models.UserInfo
        # 双下all代表着所有字段
        fields = 'all'
        labels = {
            'username':'用户名'
        }
        
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()  # models.UserInfo.objects.create(...)/update(...)
        else:
            print(modelform_obj.errors)
    return render(request, 'modelFormPage.html', locals()) 
posted @ 2022-12-21 21:22  dear丹  阅读(49)  评论(0编辑  收藏  举报