Django - form组件

form 组件

通过注册新用户的示例来介绍,form表单组件

一、校验字段的功能

# models.py

 class UserInfo(models.Model):
        name = models.CharField(max_length=32)
        pwd = models.CharField(max_length=32)
        email = models. CharField(max_length=32)
        tel = models.CharField(max_length=32)

# views.py

       from django.shortcuts import render,HttpResponse
     from django import forms
     from django.forms import widgets

     from app01.models import UserInfo

        wid_01=widgets.TextInput(attrs={"class":"form-control"})
        wid_02=widgets.PasswordInput(attrs={"class":"form-control"})

        class UserForm(forms.Form):    # 定义一个forms组件类
            name=forms.CharField(max_length=32, widget=wid_01)
            pwd=forms.CharField(max_length=32,widget=wid_02)
            r_pwd=forms.CharField(max_length=32,widget=wid_02)
            email=forms.EmailField(widget=wid_01)
            tel=forms.CharField(max_length=32,widget=wid_01)

        def register(request):  # 注册的视图函数
            if request.method=="POST":
                form=UserForm(request.POST)
                if form.is_valid():
                    print(form.cleaned_data)  # 所有干净的字段以及对应的值
                    UserInfo.objects.create(**form.cleaned_data)
                else:
                    print(form.cleaned_data) # {"字段1":"值1","字段2":"值2"}
                    print(form.errors)       # ErrorDict : {"校验错误的字段":["错误信息",]}
                    print(form.errors.get("name")) # ErrorList ["错误信息",]
                return render(request,"register.html",locals())
            form=UserForm()
            return render(request,"register.html",locals())

# register.html

<!DOCTYPE html>
        <html lang="en">
        <head>
            <meta charset="UTF-8">
            <title>Title</title>
        </head>
        <body>
            <form action="" method="post" novalidate>
                {% csrf_token %}
                <div>
                    <label for="name">用户名</label>
                    <p><input type="text" name="name" id="name"></p>
                </div>
                <div>
                    <label for="pwd">密码</label>
                    <p><input type="password" name="pwd" id="pwd"></p>
                </div>
                <div>
                    <label for="r_pwd">确认密码</label>
                    <p><input type="password" name="r_pwd" id="r_pwd"></p>
                </div>
                 <div>
                    <label for="email">邮箱</label>
                    <p><input type="text" name="email" id="email"></p>
                </div>
                <div>
                    <label for="tel">手机号</label>
                    <p><input type="text" name="tel" id="tel"></p>
                </div>
                <input type="submit">
            </form>
        </body>
        </html>

二、渲染标签的功能

方式一:(不够灵活不常用)

<form action="" method="post" novalidate >
    {% csrf_token %}
    {{ form.as_p }}
     <input type="submit" class="btn btn-default pull-right">
</form>

方式二:(一个字段一个字段的渲染)

    <form action="" method="post" novalidate >
            {% csrf_token %}
            <div>
                <label for="id_name">用户名</label>
                {{ form.name }} 
            </div>
            <div>
                <label for="id_pwd">密码</label>
                {{ form.pwd }}
            </div>
            <div>
                <label for="id_r_pwd">确认密码</label>
                {{ form.r_pwd }}
            </div>
            <div>
                <label for="id_email"> 邮箱</label>
                {{ form.email }} 
            </div>
            <div>
                <label for="id_tel"> 手机号</label>
                {{ form.tel }} 
            </div>
            <input type="submit" class="btn btn-default pull-right">
    </form>

 方式三:(通过遍历,常用的方法)

      <form action="" method="post" novalidate >
            {% csrf_token %}
            {% for field in form %}
                <div>
                    <label for="">{{ field.label }}</label>
                    {{ field }}   #后面也可以添加span标签用来展示错误信息
                </div>
            {% endfor %}
            <input type="submit" class="btn btn-default pull-right">
    </form>

三、显示错误和重置输入信息的功能

form组件校验之后,成功的字段会存储在 form.cleaned_data中,不成功的字段和错误信息会存储在 form.errors 中,具体的存储格式如下:

print(form.cleaned_data)       # {"字段1":"值1","字段2":"值2"}
print(form.errors)             # ErrorDict : {"校验错误的字段":["错误信息",]}
print(form.errors.get("name")) # ErrorList ["错误信息",]

在渲染页面的时候,可以再input标签后添加一个span标签用来显示错误信息:

# register.html

    <form action="" method="post" novalidate>
            {% csrf_token %}
    
            {% for field in form %}
                <div>
                    <label for="">{{ field.label }}</label>
                    {{ field }} 
                    <span style="color: red">{{ field.errors.0 }}</span>
                </div>
            {% endfor %}
            <input type="submit" class="btn btn-default">
    </form>

 

校验时:错误的校验顺序

1、第一层校验字段,是否符号字段的设置

2、第二层局部钩子,局部钩子是针对字段建立的

3、第三层是全局钩子,全局钩子是全局的,每一个字段都要走一遍

# views.py   formmodel中局部钩子和全局钩子的建立

from django.shortcuts import render,HttpResponse
     from django import forms
     from django.forms import widgets
     from app01.models import UserInfo

        wid_01=widgets.TextInput(attrs={"class":"form-control"})
        wid_02=widgets.PasswordInput(attrs={"class":"form-control"})

        class UserForm(forms.Form):    # 定义一个forms组件类
            name=forms.CharField(max_length=32, widget=wid_01)
            pwd=forms.CharField(max_length=32,widget=wid_02)
            r_pwd=forms.CharField(max_length=32,widget=wid_02)
            email=forms.EmailField(widget=wid_01)
            tel=forms.CharField(max_length=32,widget=wid_01)

        # 局部钩子
        def clean_name(self):
            val=self.cleaned_data.get("name")
            if not val.isdigit():
                return val
            else:
                raise ValidationError("用户名不能是纯数字!")
        # 全局钩子
        def clean(self):
            pwd=self.cleaned_data.get("pwd")
            r_pwd=self.cleaned_data.get("r_pwd")
            if pwd and r_pwd:
                if pwd==r_pwd:
                    return self.cleaned_data
                else:
                    raise ValidationError('两次密码不一致!')
            else:
                return self.cleaned_data
        def register(request):
            if request.method=="POST":
                form=UserForm(request.POST)
                if form.is_valid():
                    print(form.cleaned_data)  # 所有干净的字段以及对应的值
                    UserInfo.objects.create(**form.cleaned_data)
                else:
                    print(form.cleaned_data) # {"字段1":"值1","字段2":"值2"}
                    print(form.errors)       # ErrorDict : {"校验错误的字段":["错误信息",]}
                    print(form.errors.get("name")) # ErrorList ["错误信息",]
                    clean_error=form.errors.get("__all__")
                return render(request,"register.html",locals())
            form=UserForm()
            return render(request,"register.html",locals())
posted @ 2018-11-02 19:10  葡萄想柠檬  Views(106)  Comments(0)    收藏  举报
目录代码