forms组件笔记

为什么要用forms组件
一般前端js代码可以对数据进行普通校验,但是js可以被绕过,例如爬虫,所以后端必须做校验,保证数据安全。前端做校验可减轻后端压力。

forms特点
自动生成表单html代码
校验数据
返回校验信息及html代码

使用forms组件

from django import forms
class RegForm(forms.Form):
    name = forms.CharField(max_length=10, label='姓名', required=False, error_messages={
                            'required': '可以为空',
                           })
froms字段参数

参数名 解释 参数类型 注释
max_length
最大长度
int
 
label
输入框名字
str  
required
校验允许为空
bool
True表示不能为空
error_messages
错误提示信息
dict
key和限制字段参数一一对应
widget
输入框类型
forms.widgets.*
 
choices
选择的数据
tuple
例如((0, '男'), (1, '女'), (2, '保密')),只有ChoiceField才有
initial
默认值
int或list或str
单选为int或'checked',多选为list
validators
正则校验列表
list
例如[RegexValidator(r'^[0-9]*$', '必须是数字'),] from django.core.validators import RegexValidator
widgets参数
参数名 解释 参数类型 注释
render_value
是否返回值
bool
True会将出错数据和错误信息都返回,False只返回错误信息
attrs
html标签属性
dict
设置如class等属性
创建forms对象
regForm= RegForm(request.POST)
# regForm.data 将要进行校验的数据 dict
# regForm.cleaned_data 成功校验的数据 dict

# 校验  True校验成功 只有执行了这个方法才会执行校验
regForm.is_valid()

自定义校验(使用框架的hook)
在forms定义方法'clean_%s' % name 方法例如
name是具体的字段名
def clean_name(self):
    from django.core.exceptions import ValidationError
    if self.cleaned_data['name'] == '':
        raise ValidationError('name 不能为空')
    return self.cleaned_data['name']
重写父类clean方法,例如
def clean(self):
    if "自定义校验" != '':
        raise ValidationError('error')
    return self.cleaned_data

具体单选、复选、下拉框看例子:

from django import forms
from django.core.validators import RegexValidator
from django.core.exceptions import ValidationError


class RegForm(forms.Form):
    # 输入框
    name = forms.CharField(max_length=10,
                           label='姓名',
                           required=False,
                           error_messages={
                               'required': '可以为空',
                           })
    # 密码框
    pwd = forms.CharField(
        max_length=16,
        min_length=6,
        label='密码',
        widget=forms.widgets.PasswordInput(render_value=False),
        error_messages={
            'min_length': '密码至少6位',
            'max_length': '密码最多16位',
        })
    # 邮箱框
    email = forms.EmailField()
    # radio单选框
    gender = forms.ChoiceField(
        choices=((0, '男'), (1, '女'), (2, '保密')),
        widget=forms.widgets.RadioSelect(),
        initial=2,
    )
    # select单选下拉框
    hobby = forms.ChoiceField(
        choices=((0, '足球'), (1, '排球'), (2, '肉球')),
        widget=forms.widgets.Select(),
        initial=2,
    )
    # select多选框
    hobbys = forms.MultipleChoiceField(
        choices=((0, '足球'), (1, '排球'), (2, '肉球')),
        widget=forms.widgets.SelectMultiple(),
        initial=[1, 2]
    )
    # checkbox单选框
    # status = forms.ChoiceField(
    #     widget=forms.widgets.CheckboxInput,
    #     initial='checked',
    # )
    # checkbox多选框
    choice = forms.MultipleChoiceField(
        choices=((0, '足球'), (1, '篮球'), (2, '乒乓球')),
        widget=forms.widgets.CheckboxSelectMultiple(),
        initial=[1, 2]
    )
    # 日期选择框
    # birthday = forms.DateTimeField(
    #     widget=forms.widgets.SelectDateWidget(),
    # )
    # 正则校验
    phone = forms.CharField(
        validators=[RegexValidator(r'^[0-9]*$', '必须是数字'), RegexValidator(r'^1[3-9][0-9]{9}$', '格式不正确')]
    )
    # 从数据库取值作为参数 需自在定义__init__()方法内查询数据库内容
    city = forms.ChoiceField(
        choices=(),
        widget=forms.widgets.Select(),
        initial=2,
    )

    def clean_name(self):
        if self.cleaned_data['name'] == '':
            raise ValidationError('name 不能为空')
        return self.cleaned_data['name']

    def clean(self):
        if "自定义校验" != '':
            raise ValidationError('error')
        return self.cleaned_data

    def __init__(self, *args, **kwargs):
        super(RegForm, self).__init__(*args, **kwargs)
        self.fields['city'].widgets.choices = models.City.objects.all().values_list('id', 'name')

html页面两种展示示例

批量被p标签包住
<form action="/reg" method="post">
    {% csrf_token %}
    {{ regForm.as_p }}
    {{ regForm.errors }}
    <input type="submit" value="submit">
</form>

单个标签(推荐使用)
<form action="/reg" method="post">
    {% csrf_token %}
    <div>
        {{ regForm.name.label }}
        {{ regForm.name }}
        <span>{{ regForm.name.errors.0 }}</span>
    </div>
    <div>
        {{ regForm.pwd.label }}
        {{ regForm.pwd }}
        <span>{{ regForm.pwd.errors.0 }}</span>
    </div>
    <input type="submit" value="submit">
</form>

总结:后端必须做校验,校验方式要根据具体校验数据确定

posted @ 2019-05-02 00:39  Wuliwawa  阅读(194)  评论(0编辑  收藏  举报