• 小谈Django中的form组件


    form

    简单Form示例

    定义

    from django import forms
    
    
    class RegForm(forms.Form):
        user = forms.CharField(label="账号")
        pwd = forms.CharField(label="密码", widget=forms.PasswordInput)
    
    

    使用

    视图函数

    def reg(request):
        form_obj = RegForm()
        if request.method == 'POST':
            form_obj = RegForm(request.POST)
            if form_obj.is_valid():
                print(request.POST)
                # 上面的显示结果: 
                # <QueryDict: {'csrfmiddlewaretoken': ['wFp3cnKRpV1ZMuOdZl0rklwWkncSfULWeWaDPhaBa9eObp0Vnl4JBgZqj7MJuy4t'], 'user': ['alex'], 'pwd': ['123']}>
                print(form_obj.cleaned_data, type(form_obj.cleaned_data))
                # 上面的显示结果: 
                # {'user': 'alex', 'pwd': '123'} <class 'dict'>
                return HttpResponse('注册成功')
    
        return render(request, 'reg.html', {'form_obj': form_obj})
    

    模板

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <form action="" method="post" novalidate>
        {% csrf_token %}
    {#    {{ form_obj.as_p }}#}
    
        <p>
            <label for="{{ form_obj.user.id_for_label }}">{{ form_obj.user.label }}</label>
            {{ form_obj.user }} <span>{{ form_obj.user.errors.0 }}</span>
        </p>
        <p>
            <label for="{{ form_obj.pwd.id_for_label }}">{{ form_obj.pwd.label }}</label>
            {{ form_obj.pwd }}
        </p>
        {{ form_obj.errors }}
        <button>注册</button>
    </form>
    </body>
    </html>
    

    模板更多

    • forms.Charfield --> 字段对象
    • widget --> 插件对象

    生成所有字段的input框

    {{ form_obj.as_p }}
    

    生成某个字段的input框

    {{ form_obj.user }}
    

    某个字段的中文提示

    {{ form_obj.user.label }}
    

    某个字段的input框的ID

    {{ form_obj.user.id_for_label }}
    

    生成单个的input框并且设置label标签

    <p>
        <label for="{{ form_obj.user.id_for_label }}">{{ form_obj.user.label }}</label>
        {{ form_obj.user }}
    </p>
    <label for="{{ form_obj.user.id_for_label }}"> -> 作用: 让input框聚焦 -> 鼠标点击"账号"光标自动切到input框中
    

    所有字段的校验错误

    {{ form_obj.errors }} -> 所有字段的所有错误
    {{ form_obj.errors.0 }} -> 所有字段的第一个错误
    

    某个字段的校验错误

    {{ form_obj.user.errors }} -> 某个字段的所有错误
    {{ form_obj.user.errors.0 }} -> 某个字段的第一个错误
    

    widget=forms.PasswordInput

    # input框显示密文
    class RegForm(forms.Form)L
    	...
        pwd = forms.CharField(label='密码', widget=forms.PasswordInput)
    

    Form常用字段和插件

    • 字段用于对用户请求数据的验证 __> 与form表单校验相关
    • 插件用于自动生成HTML __> 和前段渲染相关

    所有字段

    # 导入forms模块语句:
    # from django import forms
    # 直接点进forms有下面这句, 然后点进去fields看
    from django.forms.fields import *
    
    # 看到所有的字段:
    __all__ = (
        'Field', 'CharField', 'IntegerField',
        'DateField', 'TimeField', 'DateTimeField', 'DurationField',
        'RegexField', 'EmailField', 'FileField', 'ImageField', 'URLField',
        'BooleanField', 'NullBooleanField', 'ChoiceField', 'MultipleChoiceField',
        'ComboField', 'MultiValueField', 'FloatField', 'DecimalField',
        'SplitDateTimeField', 'GenericIPAddressField', 'FilePathField',
        'SlugField', 'TypedChoiceField', 'TypedMultipleChoiceField', 'UUIDField',
    )
    

    常用字段只写了三个 ; 如果样式不够 , 可以修改widget就可以了 , 可以点出很多东西

    • 比如ChoiceField(widget=forms.RadioSelect)
    • 比如MultipleChoiceField(widget=forms.CheckboxSelectMultiple)

    Charfield

    user = forms.CharField(label="账号")
    

    ChoiceField

    gender = forms.ChoiceField(choices=(('1','男'),('2','女')),label='性别')
    

    MultipleChoiceField

    hobby = forms.MultipleChoiceField(choices=(('1','抽烟'),('2','喝酒'),('3','吐口水')), label='爱好')
    

    inital

    class RegForm(forms.Form):
        gender = forms.ChoiceField(choices=(('1','男'),('2','女')),label='性别', initial='2') # 设置默认值, 渲染在前段页面就是input框中value的值
    

    error_messages

    class RegForm(forms.Form):
        user = forms.CharField(
            label="账号",
            min_length=6,
            # 在前段显示错误的信息; 如果不设置, 显示的是默认的,英文的
            error_messages={
                'required': '不能为空!',
                'min_length':'至少是6位!'
            }
        )
    

    widget

    # 前段的input框显示密文
    class RegForm(forms.Form)L
    	...
        pwd = forms.CharField(label='密码', widget=forms.PasswordInput)
    # widget=forms.PasswordInput
    # 上下两个一样,主要看点进去"from django import forms"中的forms,看模块如何导入的.
    # widget=forms.widgets.PasswordInput
    

    required

    class RegForm(forms.Form):
        user = forms.CharField(
            # required默认是True_>必填的;改成False可以不填
            required=False,
            label="账号",
            min_length=6,
            # 在前段显示错误的信息; 如果不设置, 显示的是默认的,英文的
            error_messages={
                'required': '不能为空!',
                'min_length':'至少是6位!'
            }
        )
    

    disabled

    是否禁用

    min_length

    最小长度

    choices

    可选择的数据

    方法一 :

    class RegForm(forms.Form):
        ...
        gender = forms.ChoiceField(choices=(('1','男'),('2','女')),label='性别', initial='2')
        hobby = forms.MultipleChoiceField(choices=(('1','抽烟'),('2','喝酒'),('3','吐口水')), label='爱好')
    

    方法二 :

    class RegForm(forms.Form):
        ...
        gender = forms.ChoiceField(label='性别', initial='2')    
        
        def __init__(self, *args, **kwargs):
            super(RegForm, self).__init__(*args, **kwargs)
            # self.fields['gender'].choices = [('1','男'),('2','女')]
            # 上下两句效果一样, 但是models中gender类得添加双下str方法
            self.fields['gender'].choices = models.gender.objects.all()
    

    校验

    1. 自带的校验规则

    各个字段都有自己自带的校验规则 , 比如required...

    2. 自定义校验规则

    1. 写函数

    from django import forms
    from django.core.exceptions import ValidationError
    
    # value就是input框中填写的值
    def check_name(value):
        # 自定义校验规则
        # 如果校验合格, 什么都不做;
        # 如果校验不合格, 抛出异常(ValidationError)
        if 'alex' in value:
            raise ValidationError('不能包含alex,非法字符!')
    
    class RegForm(forms.Form):
        user = forms.CharField(
            label="账号",
            min_length=6,
            # 自定义校验规则
            validators=[check_name]
            error_messages={
                'required': '不能为空!',
                'min_length':'至少是6位!'
            }
        )
    

    2. 内置校验器

    from django import forms
    # RegexValidator是正则的内置校验器,还有很多其他的, 比如: 邮箱的,url的,ipv6的,...;可以点进去看
    from django.core.validators import RegexValidator
    
    class RegForm(forms.Form):
        phone = forms.Charfield(
            # RegexValidator()实例化一个RegexValidator的对象,第一个参数是正则表达式; 第二个参数是错误信息;
            # 可以点进去看看, 还有其他的,一般这两个就够了
            validators=[RegexValidator(r'^1[3-9]d{9}$', '手机号格式不正确')]
        )
    

    3. 局部钩子

    class RegForm(forms.Form):
        user = forms.CharField(
            label="账号",
            min_length=6,
            error_messages={
                'required': '不能为空!',
                'min_length':'至少是6位!'
            }
        )
        
        def clean_user(self):
            # 局部钩子 clean_字段名
            # 如果校验成功, 返回当前字段的值;
            # 如果校验不成功, 抛出异常;
            if 'alex' in self.cleaned_data.get('user'):
                raise ValidationError('不能包含alex,非法字符!')
            return self.cleaned_data.get('user')
    

    4. 全局钩子

    class RegForm(forms.Form):
        pwd = forms.CharField(label="密码", widget=forms.PasswordInput)
        re_pwd = forms.CharField(label="密码", widget=forms.PasswordInput)
        ...
        
        def clean(self):
            # 全局钩子
            # 如果校验成功, 返回所有字段的值;
            # 如果校验不成功, 抛出异常;
            pwd = self.cleaned_data.get('pwd')
            re_pwd = self.cleaned_data.get('re_pwd')
            if pwd == re_pwd:
                return self.cleaned_data
            else:
                # 这样错误信息就在re_pwd后面显示了,不写的话只会在所有字段的所有错误中出现;
                self.add_error('re_pwd','两次密码不一致!!!')
                raise ValidationError('两次密码不一致!')
    
    • 如果要定义的校验规则只针对于一个字段使用 __> 局部钩子 ;
    • 如果要定义的校验规则针对 一个Form中的两个字段合起来做校验( 如密码和确认密码 ) __> 全局钩子 ;
    • 如果要定义的校验规则适用于多个字段 __> 写函数或者内置校验器 , 可以只写一次函数 , 然后把函数名写到每个字段的validators中 ;
  • 相关阅读:
    pycharm运行程序,总是出现IPthony界面(IPython 6.2.1 -- An enhanced Interactive Python. Type '?' for help. PyDev console: using IPython 6.2.1)
    《剑指offer》第十一题:旋转数组的最小数字
    《剑指offer》第十题:斐波那契数列
    《剑指offer》第九题:用两个栈实现队列
    《剑指offer》第八题:二叉树的下一个节点
    《剑指offer》第七题:重建二叉树
    《剑指offer》第六题:从尾到头打印链表
    《剑指offer》第五题:替换空格
    《剑指offer》第四题:二维数组中的查找
    《剑指offer》第三题II:不修改数组找出重复的数字
  • 原文地址:https://www.cnblogs.com/richard_A/p/13804791.html
Copyright © 2020-2023  润新知