zoukankan      html  css  js  c++  java
  • Forms组件

    一、机制流程:

      1、后端接收请求数据。

      2、后端校验数据并封装校验结果发送给前端。

      3、前端根据数据校验结果渲染页面/展示提示信息。

      4、forms组件只会自动渲染获取用户输入的标签(input select radio checkbox)。

    二、前端校验与后端校验

      1、前端校验:可靠性比较低,可用可无。

      2、后端校验:比较可靠,必须要有。

    三、需要导入的模块

    from django import forms
    from django.core.validators import RegexValidator  # 正则检验相关

    四、实例:

      1、views.py -- class:

    class FormDemon(forms.Form):
        username = forms.CharField(
            min_length=3,  # 限制①,长度不得小于3
            max_length=8,  # 限制②,长度不得大于8
            label='用户名:',  # 设置贴签的内容,若不设置,则就用字段名
            initial='tom',  # 设置默认值
            error_messages={  # 设置对应限制不满足时的提示信息,若不设置,则用默认提示样式
                'min_length': '用户名长度不得小于3位',
                'max_length': '用户名长度不得大于8位',
                'required': '用户名不得为空'  # 默认限制,非空
            },
            # 设置<text>形式<input>标签的属性
            widget=forms.widgets.TextInput(
                attrs={'class': 'form-control other_class'}
            )
        )
        password = forms.CharField(
            min_length=3,
            max_length=8,
            label='密码:',
            error_messages={
                'min_length': '密码长度不得小于3位',
                'max_length': '密码长度不得大于8位',
                'required': '密码不得为空'
            },
            # 设置<password>形式<input>标签的属性
            widget=forms.widgets.PasswordInput(
                attrs={'class': 'form-control'}
            )
        )
        re_password = forms.CharField(
            min_length=3,
            max_length=8,
            label='确认密码:',
            error_messages={
                'min_length': '密码长度不得小于3位',
                'max_length': '密码长度不得大于8位',
                'required': '密码不得为空'
            },
            widget=forms.widgets.PasswordInput(
                attrs={'class': 'form-control'}
            )
        )
        email = forms.EmailField(
            label='邮箱(选填):',
            required=False,  # 设置为可为空
            error_messages={
                'invalid': '邮箱格式不正确'  # 邮箱字段的默认限制,必须符合邮箱格式
            },
            # 设置<email>形式<input>标签的属性
            widget=forms.widgets.EmailInput(
                attrs={'class': 'form-control'}
            )
        )
        phone = forms.CharField(
            label='手机号(选填):',
            required=False,
            validators=[
                # 验证手机号的正则匹配式
                # 限定11位,限定1开头,第二位只能是[3,5,6,8,9]中的一个,后9位任意数字
                RegexValidator(r'^[1][3,5,6,8,9][0-9]{9}$', '请输入正确的手机号')
            ],
            widget=forms.widgets.TextInput(
                attrs={'class': 'form-control'}
            )
        )
        gender = forms.ChoiceField(
            choices=(
                (1, ''),
                (2, ''),
                (3, '未知')
            ),
            label='性别:',
            initial=3,
            # 设置<radio>形式<select>标签的属性
            widget=forms.widgets.RadioSelect()
        )
        hobby = forms.ChoiceField(
            choices=(
                (0, '请选择(不选)'),
                (1, '旅游'),
                (2, '电子游戏'),
                (3, '太极拳'),
            ),
            initial=0,
            label='爱好(选填):',
            # 设置单选<select>标签的属性
            widget=forms.widgets.Select()
        )
        skill = forms.MultipleChoiceField(
            choices=(
                (0, '请选择(不选)'),
                (1, '倒立俯卧撑'),
                (2, '三口一头猪'),
                (3, '人体描边术'),
            ),
            initial=[0, ],
            label='特技(选填/可多选):',
            # 设置多选<select>标签的属性
            widget=forms.widgets.SelectMultiple()
        )
        # direct_login = forms.ChoiceField(
        #     label='是否直接登录:',
        #     initial='checked',
        #     # required=False,
        #     # 设置单选<checkbox>标签的属性
        #     widget=forms.widgets.CheckboxInput()
        # )
        channel = forms.MultipleChoiceField(
            choices=(
                (0, '请选择(不选)'),
                (1, '体育'),
                (2, '动漫'),
                (3, '老司机'),
            ),
            initial=[0, ],
            required=False,
            label='感兴趣的频道(选填/可多选):',
            # 设置多选<checkbox>标签的属性
            widget=forms.widgets.CheckboxSelectMultiple()
        )

      2、views.py --- def:

    def use_form(request):
        form_obj = FormDemon()  # 先生成一个同名的空的form对象用于初始页面
        if request.method == 'POST':
            form_obj = FormDemon(request.POST)  # 将 request.POST 中的键值对都放入form对象中进行校验
            # 校验准则1:类中定义的字段,除非声明可以为空,否则都需要有值,有错或不全都无法全体合法
            # 校验准则2:多传的未定义的字段会被直接忽略,所以不会被标记为非法,也不会被标记为合法
            if form_obj.is_valid():  # 是否全体合法
                return HttpResponse('信息已上传')
            print('以下是合法部分:')
            print(form_obj.cleaned_data)
            print('以下是非法部分:')
            print(form_obj.errors)
        return render(request, 'form_page.html', locals())

      3、templates:

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        {% load static %}
        <script src="{% static 'jQuery351.js' %}"></script>
        <link rel="stylesheet" href="{% static 'Bootstrap337/css/bootstrap.min.css' %}">
        <script src="{% static 'Bootstrap337/js/bootstrap.min.js' %}"></script>
    </head>
    <body>
    <div class="container">
        <p><h1>注册信息</h1></p>
        <form action="" method="post" novalidate>  <!--novalidate(取消浏览器校验)-->
    {#        <!--第一种渲染方式,代码很少,封装度高,扩展性差-->#}
    {#        {{ form_obj.as_p }}#}
    {#        {{ form_obj.as_ul }}#}
    {#        {{ form_obj.as_table }}#}
    {#        <!--第二种渲染方式,代码较多,扩展性强-->#}
    {#        <p>{{ form_obj.username.label }}{{ form_obj.username }}</p>#}
    {#        <p>{{ form_obj.password.label }}{{ form_obj.password }}</p>#}
    {#        <p>{{ form_obj.re_password.label }}{{ form_obj.re_password }}</p>#}
    {#        ...#}
            <!--第三种渲染方式,代码精简,扩展性强-->
            {% for member in form_obj %}
                <p>{{ member.label }}{{ member }}</p>
                <p style="color: red">{{ member.errors.0 }}</p>  <!--调整提示信息样式-->
            {% endfor %}
            <input type="submit" class="btn btn-info" value="提交信息">
        </form>
    </div>
    </body>
    </html>

    五、钩子函数:

      1、钩子函数在Forms组件中相当于于再次校验,可以自定义校验规则。

      2、分类:

        ①局部钩子:只能拿出某一个字段进行额外的校验。

        ②全局钩子:可以拿出所有的字段进行任选多个进行额外的校验。

      3、钩子函数在类里面自定。

      4、实例:

        # 局部钩子,指定某一个字段
        def clean_username(self):
            username_again = self.cleaned_data.get('username')  # 已通过第一次校验的才会进行再次校验
            if '4' in username_again:  # 自定义限制
                self.add_error('username', '用户名包含敏感数字')  # 编辑提示信息
            return username_again  # 编辑完放回该字段
    
        # 全局钩子,可用于所有字段
        def clean(self):
            password_again = self.cleaned_data.get('password')
            re_password_again = self.cleaned_data.get('re_password')
            if password_again != re_password_again:
                self.add_error('re_password', '两次输入的密码不一致')
            return password_again, re_password_again  # 编辑完放回拿出的字段,或直接放回全部字段
  • 相关阅读:
    UVA 10462 Is There A Second Way Left?(次小生成树&Prim&Kruskal)题解
    POJ 1679 The Unique MST (次小生成树)题解
    POJ 2373 Dividing the Path (单调队列优化DP)题解
    BZOJ 2709 迷宫花园
    BZOJ 1270 雷涛的小猫
    BZOJ 2834 回家的路
    BZOJ 2506 calc
    BZOJ 3124 直径
    BZOJ 4416 阶乘字符串
    BZOJ 3930 选数
  • 原文地址:https://www.cnblogs.com/caoyu080202201/p/13047526.html
Copyright © 2011-2022 走看看