forms组件(钩子函数(局部钩子、全局钩子)、三种页面的渲染方式、数据校验的使用)、form组件的参数以及单选多选形式

一、form是组件

后端代码

from django.shortcuts import render, redirect, HttpResponse


def ab_form(request):
    back_dict = {'username': '', 'password': ''}
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')

        if '金瓶梅' in username:
            back_dict['username'] = '不符合规范'
        if len(password) < 3 and len(password) > 20:
            back_dict['password'] = '密码的长度只能介于3位到20位的区间'

    return render(request, 'ab_form.html', locals())


from django import forms


class MyForm(forms.Form):
    username = forms.CharField(min_length=3, max_length=8, label='用户名',
                               error_messages={
                                   'min_length': '用户名最少3位',
                                   'max_length': '用户名最大8位',
                                   'required': '用户名不能为空',
                               })
    password = forms.CharField(min_length=3, max_length=8, label='密码',
                               error_messages={
                                   'min_length': '密码最少3位',
                                   'max_length': '密码最大8位',
                                   'required': '密码不能为空',
                               })
    confirm_password = forms.CharField(min_length=3, max_length=8, label='确认密码',
                               error_messages={
                                   'min_length': '确认密码最少3位',
                                   'max_length': '确认密码最大8位',
                                   'required': '确认密码不能为空',
                               })
    # email字段必须符合邮箱格式:[email protected]
    email = forms.EmailField(label='邮箱',
                             error_messages={
                                   'invalid': '邮箱格式不正确',
                                   'required': '密码不能为空',
                               })

    '''
        form_obj = views.MyForm({'username': 'json', 'password': 123, 'email': '123'})
        # 校验数据是否合法
        form_obj.is_valid()  False
        
        form_obj = views.MyForm({'username': 'json', 'password': 123, 'email': '[email protected]'})
        form_obj.is_valid()   True
       
        # 校验合法的数据有哪些
        form_obj.cleaned_data
        {'username': 'json', 'password': '123', 'email': '[email protected]'}
        
        form_obj = views.MyForm({'username': 'json', 'password': 123, 'email': '123'})
        form_obj.is_valid()  False
        
        form_obj.cleaned_data
        {'username': 'json', 'password': '123'}
        
        # 把不合法的数据找出来
        form_obj.errors  {'email': ['输入一个有效的 Email 地址。']}
        
        form_obj = views.MyForm({'username': 'json', 'password': 123})
        form_obj.is_valid()  False
        
        form_obj.errors
        {'email': ['这个字段是必填项。']}
        
    '''

    # 局部钩子
    def clean_username(self):
        # 获取到用户名
        username = self.cleaned_data.get('username')
        if '666' in username:
            # 提示前端展示错误信息
            self.add_error('username', '只含有666不行')
        # 将钩子函数钩取出来的数据再放回去
        return username

    # 全局钩子
    def clean_password(self):
        # 获取密码和确认密码
        password = self.cleaned_data.get('password')
        confirm_password = self.cleaned_data.get('confirm_password')
        if not confirm_password == password:
            self.add_error('confirm_password', '两次密码不一致')
        # 将钩子函数钩取出来的数据再放回去
        return self.cleaned_data

    '''
        钩子函数(HOOK):在特定的节点自动触发完成响应的操作
            在forms组件中有两类钩子
            1.局部钩子:
                当你需要给单个字段增加校验规则的时候可以使用
            2.全局钩子:
                当你需要给多个字段增加校验规则的时候可以使用

            案例:
                1.校验用户名中不能含有666 只是校验username字段,局部钩子
                2.校验密码和确认密码是否一致 password和confirm两个字段  全局钩子
        '''


def index(request):
    # 1.先产生一个空对象
    # 里面的label属性默认展示的是类中定义的字段首字母大写的形式,
    # 也可以自行修改,如:label='用户名'
    form_obj = MyForm()
    if request.method == 'POST':

        # 获取用户数据并且校验
        '''
            1.获取数据繁琐
            2.校验数据需要构造成字典的格式传入才行
            PS:但是 request.POST 可以看成是一个字典
        '''
        # 3.校验数据
        form_obj = MyForm(request.POST)
        # 4.判断数据是否合法
        if form_obj.is_valid():
            # 5.若合法,操作数据库,存储数据
            return HttpResponse('OK')

        # 不合法,如何将错误信息展示到前端?

    # 2.直接将该空对象传递给html页面

    return render(request, 'index.html', locals())

2.前端值index

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>

    {% load static %}
    <script src="{% static 'js/jquery.min.js' %}">script>
    <link href="{% static 'bootstrap/css/bootstrap.min.css' %}" rel="stylesheet">
    <script src="{% static 'bootstrap/js/bootstrap.min.js' %}">script>
    <script src="{% static 'layer/layer.js' %}">script>

head>
<body>

<form action="" method="post" novalidate>
    <p>第一种页面渲染方式: 代码书写少,封装程度太高了,不便于后续的扩展,一般只在本地测试使用p>
{#    {{ form_obj.as_p }}#}

    <p>第二种页面渲染方式:可扩展性很强,但是需要书写的代码太多,一般情况下不用p>
{#    {{ form_obj.as_ul }}#}
{#    <p>{{ form_obj.username.label }}:{{ form_obj.username }}p>#}
{#    <p>{{ form_obj.password.label }}:{{ form_obj.password }}p>#}
{#    <p>{{ form_obj.email.label }}:{{ form_obj.email }}p>#}

    <p>第三种页面渲染方式(推荐使用):代码书写简单,并且扩展性高p>
{#    {{ form_obj.as_table }}#}
    {% for form in form_obj %}
        <p>
            {{ form.label }}:{{ form}}
            <span style="color: red">{{ form.errors.0 }}span>
        p>
    {% endfor %}
    <input type="submit" class="btn btn-info">
    
form>


body>
html>

3.前端之ab_form

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Titletitle>

    {% load static %}
    <script src="{% static 'js/jquery.min.js' %}">script>
    <link href="{% static 'bootstrap/css/bootstrap.min.css' %}" rel="stylesheet">
    <script src="{% static 'bootstrap/js/bootstrap.min.js' %}">script>
    <script src="{% static 'layer/layer.js' %}">script>

head>
<body>

<form action="" method="post">
    <div class="container">
        <div class="row">
            <div class="col-md-8 col-md-offset-2">
                <p>username :
                    <input type="text" name="username">
                    <span style="color: darkred">{{ back_dict.username }}span>
                p>
                <p>password:
                    <input type="password" name="password">
                    <span style="color: darkred">{{ back_dict.password }}span>
                p>
                <input type="submit" class="btn btn-info">
            div>
        div>
    div>


form>

body>
html>

4.form组件的参数以及单选多选形式

class MyForm(forms.Form):
    username = forms.CharField(min_length=3, max_length=8,
                               label='用户名',
                               initial='lin',
                               required=False,
                               error_messages={
                                   'min_length': '用户名最少3位',
                                   'max_length': '用户名最大8位',
                                   'required': '用户名不能为空',
                               },
                               widget=forms.widgets.TextInput(attrs={'class': 'form-control', 'username': 'lin'})
                               )
    password = forms.CharField(min_length=3, max_length=8, label='密码',
                               error_messages={
                                   'min_length': '密码最少3位',
                                   'max_length': '密码最大8位',
                                   'required': '密码不能为空',
                               },
                               widget=forms.widgets.PasswordInput()
                               )
    confirm_password = forms.CharField(min_length=3, max_length=8, label='确认密码',
                               error_messages={
                                   'min_length': '确认密码最少3位',
                                   'max_length': '确认密码最大8位',
                                   'required': '确认密码不能为空',
                               },
                               widget=forms.widgets.PasswordInput()
                               )
    # email字段必须符合邮箱格式:[email protected]
    email = forms.EmailField(label='邮箱',
                             error_messages={
                                   'invalid': '邮箱格式不正确',
                                   'required': '密码不能为空',
                               },
                             widget=forms.widgets.EmailInput()
                             )
    # 还支持正则校验
    phone = forms.CharField(
        validators=[
            RegexValidator(r'^[0-9]+$', '请输入数字'),
            RegexValidator(r'^159[0-9]+$', '数字必须以159开头')
        ],
    )
    # 选择
    gender = forms.ChoiceField(
        choices=((1, '男'), (2, '女'), (3, '保密')),
        label='性别',
        initial=3,
        widget=forms.widgets.RadioSelect()
    )
    # 多选
    hobby = forms.ChoiceField(
        choices=((1, '篮球'), (2, '足球'), (3, '双色球')),
        label='爱好',
        initial=3,
        widget=forms.widgets.Select()
    )
    # 多选
    hobby1 = forms.MultipleChoiceField(
        choices=((1, '篮球'), (2, '足球'), (3, '双色球')),
        label='爱好',
        initial=[1, 3],
        widget=forms.widgets.SelectMultiple()
    )
    # 单选checkbox
    keep = forms.ChoiceField(
        label='是否记住密码',
        initial='checked',
        widget=forms.widgets.CheckboxInput()
    )
    # 多选checkbox
    hobby2 = forms.MultipleChoiceField(
        choices=((1, '篮球'), (2, '足球'), (3, '双色球')),
        label='爱好',
        initial=[1, 3],
        widget=forms.widgets.CheckboxSelectMultiple()
    )

    '''
    forms组件其他参数及补充知识点:
        label 字段名
        error_messages  自定义报错信息
        invalid    邮箱格式提示信息
        initial    设置默认值
        required   控制字段是否必填
        
        
    字段没有样式:
        针对不同类型的input如何修改?
            通过 widget
            如:
            widget=forms.widgets.TextInput()
            widget=forms.widgets.TextInput(attrs={'class': 'form-control', 'username': 'lin'})
                注意:需要什么样式,自行添加, 若是多个属性值,直接空格隔开即可
            widget=forms.widgets.PasswordInput()
            widget=forms.widgets.EmailInput()
        text
        password
        date
        radio
        checkbox
        ...
        
    '''


    '''
        form_obj = views.MyForm({'username': 'json', 'password': 123, 'email': '123'})
        # 校验数据是否合法
        form_obj.is_valid()  False
        
        form_obj = views.MyForm({'username': 'json', 'password': 123, 'email': '[email protected]'})
        form_obj.is_valid()   True
       
        # 校验合法的数据有哪些
        form_obj.cleaned_data
        {'username': 'json', 'password': '123', 'email': '[email protected]'}
        
        form_obj = views.MyForm({'username': 'json', 'password': 123, 'email': '123'})
        form_obj.is_valid()  False
        
        form_obj.cleaned_data
        {'username': 'json', 'password': '123'}
        
        # 把不合法的数据找出来
        form_obj.errors  {'email': ['输入一个有效的 Email 地址。']}
        
        form_obj = views.MyForm({'username': 'json', 'password': 123})
        form_obj.is_valid()  False
        
        form_obj.errors
        {'email': ['这个字段是必填项。']}
        
    '''

    # 局部钩子
    def clean_username(self):
        # 获取到用户名
        username = self.cleaned_data.get('username')
        if '666' in username:
            # 提示前端展示错误信息
            self.add_error('username', '只含有666不行')
        # 将钩子函数钩取出来的数据再放回去
        return username

    # 全局钩子
    def clean_password(self):
        # 获取密码和确认密码
        password = self.cleaned_data.get('password')
        confirm_password = self.cleaned_data.get('confirm_password')
        if not confirm_password == password:
            self.add_error('confirm_password', '两次密码不一致')
        # 将钩子函数钩取出来的数据再放回去
        return self.cleaned_data

    '''
        钩子函数(HOOK):在特定的节点自动触发完成响应的操作
            在forms组件中有两类钩子
            1.局部钩子:
                当你需要给单个字段增加校验规则的时候可以使用
            2.全局钩子:
                当你需要给多个字段增加校验规则的时候可以使用

            案例:
                1.校验用户名中不能含有666 只是校验username字段,局部钩子
                2.校验密码和确认密码是否一致 password和confirm两个字段  全局钩子
        '''

你可能感兴趣的:(python01,django,django,python)