form Form component

form Form component

When submitting data to the back end before we use a form in an HTML page form, will write the label to obtain user input and label them with a form wrap.

At the same time we all need to do in a lot of scenes of user input validation, such as checking whether the user input, the input length and format is not correct. If the user input has an error requires appropriate error message corresponding to the location on the page ..

Django form component to achieve the functions described above.

To sum up, in fact, the main function of form components as follows:

  • HTML tags generated pages available
  • To verify the data submitted by users
  • Keep last Input content

First, write your own check

Filter keywords such as:

  • Registration function,
    • Registered user name can not contain sensitive words such as jinpingmei, if given input error
    • The password entered by the user can not be less than three, less than three mask prompts the user if the password is too short
  • Note: check data parity typically have front and rear ends, the front end of the check optional but even then regressed, must also have the rear end of the front end of the check word may anyway have no checksum must verify rear! ! !
<body>
<form action="" method="post">
    {{ back_dic }}
    <p>username:
        <input type="text" name="username">
        <span style="color:red">{{ back_dic.username }}</span>
    </p>
    <p>password:<input type="text" name="password">
        <span style="color:red">{{ back_dic.password }}</span>
    </p>
    <input type="submit">
</form>
</body>
# urls.py
from app01 import views
urlpatterns = [
    url(r'^register/', views.register),
]
# views.py
def register(request):
    back_dic = {'username': '', 'password': ''}
    if request.method == 'POST':
        username = request.POST.get('username')
        password = request.POST.get('password')

        if 'jinpingmei' in username:
            back_dic['username'] = "敏感词汇"

        if len(password) < 3:
            back_dic['password'] = '长度不能小于三'

    return render(request, '03register.html', locals())

to sum up:

  • Set up the front page to make their own
  • To do their own test data
  • Display error messages do it yourself

img

Second, the use of the form component

Importingfrom django import forms

Define a class MyRegForm 2.1


class MyRegForm(forms.Form):
    username = forms.CharField(min_length=3, max_length=5)
    password = forms.CharField(min_length=3, max_length=6)
    email = forms.EmailField()

2.2 check data

#校验数据导入模块
from app01 import views
# 1. 给自定义的类传一个字典
obj = views.MyRegForm({'username':'randy',"password":"123", 'email:':'12345'})
# 2.判断数据是否全部合法
obj.is_valid()
Out[8]: False
# 3.查看符合数据的字段
obj.cleaned_data
Out[9]: {'username': 'randy', 'password': '123'}
# 4.查看不符合条件的数据,以及显示符合数据的原因
obj.errors
Out[10]: {'email': ['This field is required.']}

img

# 5.校验数据的时候 默认情况下类里面所有的字段都必须传值
obj = views.MyRegForm({'username':'randy',"password":"12"})
obj.is_valid()
Out[12]: False
obj.errors
Out[13]: 
{'password': ['Ensure this value has at least 3 characters (it has 2).'],
 'email': ['This field is required.']}

# 6.默认情况下可以多传 但是绝对不能少传
obj = views.MyRegForm({'username':'randy','password':'123','email':'[email protected]','res':'ooo'})
obj.is_valid()
Out[15]: True

2.3 page rendering in three ways

forms components will help you render obtain user input (input, select, drop-down box ...) tags need to manually write the submit button

# urls.py
from app01 import views
urlpatterns = [
     url(r'^formss/', views.formss),
]
# views.py
def formss(request):
    # 1. 生成一个空对象
    form_obj = MyRegForm() # 两个对象名要相同
    if request.method == 'POST':
        #2. 获取用户提交的数据
        print(request.POST)

        # 3.记住与form组件帮助我们校验
        form_obj = MyRegForm(request.POST)

        # 4 判断用户输入的数据是否符合校验规则
        if form_obj.is_valid():
            return HttpResponse("上传的数据没有问题")
        else:
            return HttpResponse("上传的数据存在问题")

    return render(request, '04formss表单校验.html', locals())

Rendering a page

<form action="" method="post" novalidate>
    <h2>页面渲染方式一</h2>
    {{ form_obj.as_p }}  <!--as_p指定包裹的标签,采用p标签包裹-->
    {#{{ form_obj.as_ul }}#}
    <input type="submit" value="验证">
</form>

img

img

The first front page rendering by: too high a level package style tag and convenient adjustment parameter poor scalability (not recommended)

<form action="" method="post" novalidate>
      <h2>页面渲染方式二</h2>
    <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>
    <input type="submit" value="验证">
</form>

img

img

The second way to render the page: inadequate at higher scalability that you need more than hand-written code (not recommended)

<form action="" method="post" novalidate>
    <h2>页面渲染方式三</h2>
    {% for res in form_obj %}
        <p>
            {{ res.label }}:{{ res }}
            <span style="color:red">{{ res.errors.0 }}</span>
        </p>
    {% endfor %}
    <input type="submit" value="验证">
</form>

img

The third rendering of the front page of the way: the amount of code and scalability are high (recommended), display an error message with an object point errors.0

Three, form other authentication parameters

from django import forms
from django.forms import widgets  # 当你forms点不出来的时候 你可以手动导入一下
from django.core.validators import RegexValidator
class MyRegForm(forms.Form):
    username = forms.CharField(min_length=3, max_length=5,
                               error_messages={
                                   'min_length': '用户最短三位',
                                   'max_length': '用户最长八位',
                                   'required': '用户名不能为空',
                               }, initial='设置初始值', required=False,
                               widget=forms.widgets.TextInput(attrs={'class': 'form-control other'}))
    password = forms.CharField(min_length=3, max_length=6,
                               error_messages={
                                   'min_length': '密码最短三位',
                                   'max_length': '密码最长八位',
                                   'required': '密码不能为空'
                               })
    confirm_password = forms.CharField(min_length=3, max_length=8, label='确认密码',
                                       error_messages={
                                           'min_length': '确认密码最短三位',
                                           'max_length': '确认密码最长八位',
                                           'required': '确认密码不能为空'
                                       })
    email = forms.EmailField(label='邮箱',
                             error_messages={
                                 'required': '邮箱不能为空',
                                 'invalid': '邮箱格式不正确'
                             }, required=False)
    phone = forms.CharField(label='手机号',validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')])

Parameter Description:

  • min_length: The minimum length of the data
  • max_length: The maximum length of data
  • error_messages: corresponding to given information,
  • required: can not be empty
  • widget: add style to the label, can be achieved by adding more spaces
  • validators: supports regular expressions

Fourth, the hook function

forms provided by the label check, but also can not satisfy you, you can use the hook function to add additional verification

4.1 partial hook function

class MyRegForm(forms.Form):
    username = forms.CharField(min_length=3, max_length=10)
    password = forms.CharField(min_length=3, max_length=6)
    confirm_password = forms.CharField(min_length=3, max_length=8, label='确认密码')
     email = forms.EmailField(label='邮箱')
    # 当需要对某一个字段数据进行额外的数据校验,可以使用钩子函数
    # 针对单个字段,使用局部钩子
    def clean_username(self):
        # 获取标签
        username = self.cleaned_data.get("username")
        if 'jinpingmei' in username:
            # 给username字段下面提示错误信息
            # raise ValidationError("输入敏感词汇)
            self.add_error('username', '输入敏感词汇')
        return username

img

4.2 global hook function

class MyRegForm(forms.Form):
    username = forms.CharField(min_length=3, max_length=10)
    password = forms.CharField(min_length=3, max_length=6)
    confirm_password = forms.CharField(min_length=3, max_length=8, label='确认密码')
    email = forms.EmailField(label='邮箱')
 
    # 针对多个字段的校验使用全局钩子
    def clean(self):
        username = self.cleaned_data.get('username')
        confirm_password = self.cleaned_data.get("confirm_password")

        if not confirm_password == username:
            self.add_error("confirm_password", "两次密码输入不一样")

        return self.cleaned_data

img

Five other fields constraints

Common Fields with plug-ins

When creating Form class, mainly related to the field of [] and [] plug, field is used to authenticate the user requesting the data, for automatically generating the HTML plug;

initial

The initial value, the initial value input box inside.

class LoginForm(forms.Form):
    username = forms.CharField(
        min_length=8,
        label="用户名",
        initial="张三"  # 设置默认值
    )
    pwd = forms.CharField(min_length=6, label="密码")

error_messages

Rewrite error message.

class LoginForm(forms.Form):
    username = forms.CharField(
        min_length=8,
        label="用户名",
        initial="张三",
        error_messages={
            "required": "不能为空",
            "invalid": "格式错误",
            "min_length": "用户名最短8位"
        }
    )
    pwd = forms.CharField(min_length=6, label="密码")

password

class LoginForm(forms.Form):
    ...
    pwd = forms.CharField(
        min_length=6,
        label="密码",
        widget=forms.widgets.PasswordInput(attrs={'class': 'c1'}, render_value=True)
    )

radioSelect

Value is a string of single radio

class LoginForm(forms.Form):
    username = forms.CharField(
        min_length=8,
        label="用户名",
        initial="张三",
        error_messages={
            "required": "不能为空",
            "invalid": "格式错误",
            "min_length": "用户名最短8位"
        }
    )
    pwd = forms.CharField(min_length=6, label="密码")
    gender = forms.fields.ChoiceField(
        choices=((1, "男"), (2, "女"), (3, "保密")),
        label="性别",
        initial=3,
        widget=forms.widgets.RadioSelect()
    )

Radio Select

class LoginForm(forms.Form):
    ...
    hobby = forms.ChoiceField(
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
        label="爱好",
        initial=3,
        widget=forms.widgets.Select()
    )

Select multiple choice

class LoginForm(forms.Form):
    ...
    hobby = forms.MultipleChoiceField(
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"), ),
        label="爱好",
        initial=[1, 3],
        widget=forms.widgets.SelectMultiple()
    )

Radio checkbox

class LoginForm(forms.Form):
    ...
    keep = forms.ChoiceField(
        label="是否记住密码",
        initial="checked",
        widget=forms.widgets.CheckboxInput()
    )

Multi-select checkbox

class LoginForm(forms.Form):
    ...
    hobby = forms.MultipleChoiceField(
        choices=((1, "篮球"), (2, "足球"), (3, "双色球"),),
        label="爱好",
        initial=[1, 3],
        widget=forms.widgets.CheckboxSelectMultiple()
    )

choice field considerations

When using the select tag, you need to pay attention to choices of configuration options can be obtained from the database, but because it is the value of static fields taken not immediately update, you need to override the constructors choice in order to achieve real-time updates.

method one:

from django.forms import Form
from django.forms import widgets
from django.forms import fields

 
class MyForm(Form):
 
    user = fields.ChoiceField(
        # choices=((1, '上海'), (2, '北京'),),
        initial=2,
        widget=widgets.Select
    )
 
    def __init__(self, *args, **kwargs):
        super(MyForm,self).__init__(*args, **kwargs)
        # self.fields['user'].choices = ((1, '上海'), (2, '北京'),)
        # 或
        self.fields['user'].choices = models.Classes.objects.all().values_list('id','caption')

Second way:

from django import forms
from django.forms import fields
from django.forms import models as form_model

 
class FInfo(forms.Form):
    authors = form_model.ModelMultipleChoiceField(queryset=models.NNewType.objects.all())  # 多选
    # authors = form_model.ModelChoiceField(queryset=models.NNewType.objects.all())  # 单选

Django Form All built-in fields

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,              最小值
 
FloatField(IntegerField)
    ...
 
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
 
DurationField(Field)            时间间隔:%d %H:%M:%S.%f
    ...
 
RegexField(CharField)
    regex,                      自定制正则表达式
    max_length=None,            最大长度
    min_length=None,            最小长度
    error_message=None,         忽略,错误信息使用 error_messages={'invalid': '...'}
 
EmailField(CharField)      
    ...
 
FileField(Field)
    allow_empty_file=False     是否允许空文件
 
ImageField(FileField)      
    ...
    注:需要PIL模块,pip3 install Pillow
    以上两个字典使用时,需要注意两点:
        - form表单中 enctype="multipart/form-data"
        - view函数中 obj = MyForm(request.POST, request.FILES)
 
URLField(Field)
    ...
 
 
BooleanField(Field)  
    ...
 
NullBooleanField(BooleanField)
    ...
 
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= ''            空值的默认值
 
MultipleChoiceField(ChoiceField)
    ...
 
TypedMultipleChoiceField(MultipleChoiceField)
    coerce = lambda val: val   对选中的每一个值进行一次转换
    empty_value= ''            空值的默认值
 
ComboField(Field)
    fields=()                  使用多个验证,如下:即验证最大长度20,又验证邮箱格式
                               fields.ComboField(fields=[fields.CharField(max_length=20), fields.EmailField(),])
 
MultiValueField(Field)
    PS: 抽象类,子类中可以实现聚合多个字典去匹配一个值,要配合MultiWidget使用
 
SplitDateTimeField(MultiValueField)
    input_date_formats=None,   格式列表:['%Y--%m--%d', '%m%d/%Y', '%m/%d/%y']
    input_time_formats=None    格式列表:['%H:%M:%S', '%H:%M:%S.%f', '%H:%M']
 
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类型

Field validation

RegexValidator validator

from django.forms import Form
from django.forms import widgets
from django.forms import fields
from django.core.validators import RegexValidator
 
class MyForm(Form):
    user = fields.CharField(
        validators=[RegexValidator(r'^[0-9]+$', '请输入数字'), RegexValidator(r'^159[0-9]+$', '数字必须以159开头')],
    )

Custom validation function

import re
from django.forms import Form
from django.forms import widgets
from django.forms import fields
from django.core.exceptions import ValidationError
 
 
# 自定义验证规则
def mobile_validate(value):
    mobile_re = re.compile(r'^(13[0-9]|15[012356789]|17[678]|18[0-9]|14[57])[0-9]{8}$')
    if not mobile_re.match(value):
        raise ValidationError('手机号码格式错误')
 
 
class PublishForm(Form):
 
 
    title = fields.CharField(max_length=20,
                            min_length=5,
                            error_messages={'required': '标题不能为空',
                                            'min_length': '标题最少为5个字符',
                                            'max_length': '标题最多为20个字符'},
                            widget=widgets.TextInput(attrs={'class': "form-control",
                                                          'placeholder': '标题5-20个字符'}))
 
 
    # 使用自定义验证规则
    phone = fields.CharField(validators=[mobile_validate, ],
                            error_messages={'required': '手机不能为空'},
                            widget=widgets.TextInput(attrs={'class': "form-control",
                                                          'placeholder': u'手机号码'}))
 
    email = fields.EmailField(required=False,
                            error_messages={'required': u'邮箱不能为空','invalid': u'邮箱格式错误'},
                            widget=widgets.TextInput(attrs={'class': "form-control", 'placeholder': u'邮箱'}))

Guess you like

Origin www.cnblogs.com/randysun/p/11761921.html