Form表单验证(基础)

Form表单验证本质:

  • 就是一个类class MyForm(forms.Form) 继承了forms.Form

form组件的主要功能如下:

  • 生成页面可用的HTML标签
  • 对用户提交的数据进行校验
  • 保留上次输入内容

使用form组件添加用户信息的功能

# 自定义Form类

from django import forms

class UserInfoForm(Form):
    # 表单的字段名字最好和model的字段名字一致,方便操作
    username = forms.CharField(
        min_length=5,
        max_length=32,
        error_messages={
            'required':'不能为空',
            'min_length':'最短5个字符',
            'max_length':'最长32的字符'
        },
        label="用户名",
    )
pwd
= forms.CharField( min_length=6, # Form表单默认生成<input type='text'/> 标签 如果要修改可以使用widgets组件 或者 填写 attr属性 # widget=widgets.PasswordInput() widget=widgets.TextInput(attrs={'type': 'password'}) ) #------ 生成select标签的两种形式 ----- # 第一种后台接受到的数据是整数{'city_id': 1} city_id = forms.IntegerField( widget=widgets.Select( choices=[(1,'北京'),(2,'天津'),(3,'上海')], # 可以添加option标签 接受列表格式的数据 每个元组对应value 和 text文本 attrs = {'id': '001', 'class':'cls-01','diy':'自定义'} # 可以设置属性值 添加id class 名 自定义属性 ) ) # 第二种接受的数据是字符串{'hobby': '1'} hobby = forms.ChoiceField( choices=((1, "篮球"), (2, "足球"), (3, "双色球"),), label="爱好", initial=3, widget=forms.widgets.Select() )
# html代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>用户注册</title>
</head>
<body>
    <h1>用户信息注册</h1>
    <form method="POST" action="/add_userinfo.html">
        {% csrf_token %}
        <p>
            {{ userinfo_form.username }}{{ login_form.errors.username.0 }}
        </p>
        <p>
            {{ userinfo_form.pwd }}{{ userinfo_form.errors.pwd.0 }}
        </p>
        <p>
            {{ userinfo_form.city_id }}{{userinfo_form.errors.city_id.0 }}
        </p>
        <p>
            {{ userinfo_form.hobby }}{{ userinfo_form.errors.hobby.0 }}
        </p>
        <input type="submit" value="提交" />
    </form>
</body>
</html>
# view.py 
def userinfo(request):
    if request.method == 'GET':
        userinfo_form = UserInfoForm()
        return render(request, 'userinfo.html', {'userinfo_form': userinfo_form})
    else:
        userinfo_form = UserInfoForm(request.POST)
        # 校验数据的有效性 成功则向数据库添加数据
        if userinfo_form.is_valid():
            models.UserInfo.objects.create(**userinfo_form.cleaned_data)
            return redirect('/userinfo.html')
        else:
            #失败则将用户提交的表单数据和表单html再次返回给用户
            return render(request, 'userinfo.html', {'userinfo_form': userinfo_form})
Form表单字段的参数:
#  参数分为2大类
# Field(
# 1. 数据校验
# required=True, 不可以为空,默认可以不写
# error_messages=None, 设置错误信息dict格式{'required':'不能为空','min_length':'长度最小是5'}
# validators=(), 自定义正则规则,传入一个列表, 可以传入多个规则 也可以传入函数 def 函数名(value):pass

# 2. 自动生成html标(除了widget,其他不建议使用)
# widget=None, 自定义显示在前端的表单控件
# initial 默认显示的值
# label=None,
# help_text='',
# show_hidden_initial=False,
# localize=False,
# disabled=False,
# label_suffix=None
# )

Form表单的所有内置字段:

  
Field
    required=True            是否运行为空
    widget=None,            HTML插件
    label=None,                用于生成label标签或显示内容
    initial=None,               初始值
    help_text=' ',              帮助信息(在标签旁显示)
    error_messages=None  错误信息{'required': '不能为空', 'invalid': '格式错误'}
    validators=[]                自定义验证规则
    localize=False,              是否支持本地化
    disabled=False,              是否可以编辑
    label_suffix=None            Label内容后缀


CharField(Field)
    max_length=None        最大长度
    min_length=None        最小长度
    strip=True                    是否移除用户输入空白


IntegerField(Field)
    max_value=None,              最大值
    min_value=None,              最小值


DecimalField(IntegerField)
    max_value=None,              最大值
    min_value=None,              最小值
    max_digits=None,             总长度
    decimal_places=None,         小数位长度


BaseTemporalField(Field)
    input_formats=None          时间格式化


DateField(BaseTemporalField)    格式:2015-09-01
TimeField(BaseTemporalField)    格式:11:12
DateTimeField(BaseTemporalField)格式:2015-09-01 11:12


RegexField(CharField)
    regex,                      自定制正则表达式
    max_length=None,            最大长度
    min_length=None,            最小长度
    error_message=None,         忽略,错误信息使用 error_messages={'invalid': '...'}


FileField(Field)
    allow_empty_file=False     是否允许空文件


ImageField(FileField)      
    ...
    注:需要PIL模块,pip3 install Pillow
    以上两个字典使用时,需要注意两点:
        - form表单中 enctype="multipart/form-data"
        - view函数中 obj = MyForm(request.POST, request.FILES)


ChoiceField(Field)
    choices=(),                选项,如:choices = ((0,'上海'),(1,'北京'),)
    required=True,             是否必填
    widget=None,               插件,默认select插件
    label=None,                Label内容
    initial=None,              初始值
    help_text='',              帮助提示


ModelChoiceField(ChoiceField)
    ...                        django.forms.models.ModelChoiceField
    queryset,                  # 查询数据库中的数据
    empty_label="---------",   # 默认空显示内容
    to_field_name=None,        # HTML中value的值对应的字段
    limit_choices_to=None      # ModelForm中对queryset二次筛选


ModelMultipleChoiceField(ModelChoiceField)
    ...                        django.forms.models.ModelMultipleChoiceField


TypedChoiceField(ChoiceField)
    coerce = lambda val: val   对选中的值进行一次转换
    empty_value= ''            空值的默认值


TypedMultipleChoiceField(MultipleChoiceField)
    coerce = lambda val: val   对选中的每一个值进行一次转换
    empty_value= ''            空值的默认值


FilePathField(ChoiceField)     文件选项,目录下文件显示在页面中
    path,                      文件夹路径
    match=None,                正则匹配
    recursive=False,           递归下面的文件夹
    allow_files=True,          允许文件
    allow_folders=False,       允许文件夹
    required=True,
    widget=None,
    label=None,
    initial=None,
    help_text=''


GenericIPAddressField
    protocol='both',           both,ipv4,ipv6支持的IP格式
    unpack_ipv4=False          解析ipv4地址,如果是::ffff:192.0.2.1时候,可解析为192.0.2.1, PS:protocol必须为both才能启用


SlugField(CharField)           数字,字母,下划线,减号(连字符)


UUIDField(CharField)           uuid类型

Django Form内置字段

initial 

  设置初始值的两种方式: 

# 一、在Form表单字段中设置初始值

class UserInfoForm(Form):
    # 表单的字段名字最好和model的字段名字一致,方便操作
    username = fields.CharField(
        min_length=5,
        max_length=32,
        initial='我是在html上首次显示的初始值' # 设置初始值
    )
    ...

# 二、实例化Form类时设置初始值

def test(request):
    userinfo_form = UserInfoForm(initial={'字段名1': '初始值1','字段名2': '初始值2'})
    return render(request, 'userinfo.html', {'userinfo_form':userinfo_form})

自定义错误信息 error_messages

class UserInfoForm(Form):
   
    username = fields.CharField(
        min_length=5,
        max_length=32,
        error_messages={
            'required':'不能为空',
            'min_length':'最短5个字符',
            'max_length':'最长32的字符'
        }
    )

 给Form指定字段的标签添加属性

city_id = fields.IntegerField(
        widget=widgets.Select(
            choices=[(1,'北京'),(2,'天津'),(3,'上海'),(4,"武汉")], # 可以添加option标签 接受列表格式的数据 每个元组对应value 和 text文本
            attrs = {'id': '001', 'class':'cls-01','diy':'自定义'}  # 可以设置属性值 添加id class 名 自定义属性
        )
    )

使用内置字段 forms.RegexField 和参数 validators 自定义验证规则

  #  forms.RegexField

phone = forms.RegexField(r'^1[35678]\d{11}$', max_length=11)

  #  validators

phone = forms.CharField(
        min_length=11,
        max_length=11,
        validators=[RegexValidator(r'^1[345678]\d{9}$', '手机号格式不正确'), RegexValidator(),...] # 可以传入多个规则
    ) 

  # 还可以自定义校验函数传入 validators

# 自定义校验函数
def phone_validate(value):
    # 拿用户填写的手机号去数据库中校验
    is_exits = models.PhoneInfo.objects.filter(phone=value)
    if is_exits:
        # 如果手机号被注册,不能再注册
        raise ValidationError("该手机号已经被注册")
    else:
        return value


phone = forms.CharField(
        max_length=11,
        validators=[RegexValidator(r'^1[345678]\d{9}$', '手机号格式不正确'), phone_validate]
    )
 

猜你喜欢

转载自www.cnblogs.com/liubailiang/p/11470749.html