form组件

正常情况下我们写个注册页面,利用form表单会是这样写

reg.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/reg/" method="post">
    {% csrf_token %}
    <p>姓名 <input type="text" name="user"></p><p>密码 <input type="password" name="pwd"></p><p>确认密码 <input type="password" name="repeat_pwd"></p><p>邮箱 <input type="email" name="email"></p><input type="submit"></form>
</body>
</html>

视图函数中view.py

def reg(request):
    return render(request,"reg.html")

上面我们需要将数据传送后端然后数据验证,然后返回前端。

 

 我们可以利用form组件进行一些表单的限制

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/reg/" method="post">
    {% csrf_token %}
<p>姓名 {{ regForm.username }}</p>
    <p>密码 {{ regForm.password }}</p>
    <p>确认密码 {{ regForm.repeat_password }}</p>
    <p>邮箱 {{ regForm.email }}</p>
    <input type="submit">
</form>
</body>
</html>

view.py

#引入form组件进行表单验证
from django import forms
class RegForm(forms.Form):
    username=forms.CharField(max_length=12,min_length=6)
    password=forms.CharField(max_length=20,min_length=8)
    repeat_password=forms.CharField(max_length=20,min_length=8)
    email=forms.EmailField()#email类型

def reg(request):
    #实例化
    regForm=RegForm()
    return render(request,"reg.html",locals())

我们在RegForm中对字段进行一些限制

设置密码为密文,更改RegForm类

from django import forms
from django.forms import widgets#引入widgets
class RegForm(forms.Form):
    username=forms.CharField(max_length=12,min_length=6)
    password=forms.CharField(
        widget=widgets.PasswordInput,
        max_length=20,
        min_length=8)
    repeat_password=forms.CharField(
        widget=widgets.PasswordInput,
        max_length=20,
        min_length=8)
    email=forms.EmailField()#email类型
widgets还可以设置下拉菜单,widget=widgets.Select(choices=((1,'上海'),(2,'北京'),))

我们还可以设置报错说明

from django import forms
from django.forms import widgets
class RegForm(forms.Form):
    username=forms.CharField(max_length=12,min_length=6,
                             error_messages={"min_length":"太你妹少了多写点行么","required":"你确定你用户名叫空么???"})
    password=forms.CharField(
        widget=widgets.PasswordInput,
        max_length=20,
        min_length=8)
    repeat_password=forms.CharField(
        widget=widgets.PasswordInput,
        max_length=20,
        min_length=8)
    email=forms.EmailField()#email类型

其实上面只是一些浏览器渲染做的限制,我们用万能ie浏览器,不管你输入什么都会给你提交到后端,所以我们需要在后端
对输入内容做判断处理
#引入form组件进行表单验证
from django import forms
from django.forms import widgets
class RegForm(forms.Form):
    username=forms.CharField(max_length=12,min_length=6,
                             error_messages={"min_length":"太你妹少了多写点行么","required":"你确定你用户名叫空么???"})
    password=forms.CharField(
        widget=widgets.PasswordInput(attrs={"egon":1234}),
        max_length=20,
        min_length=8)
    repeat_password=forms.CharField(
        widget=widgets.PasswordInput,
        max_length=20,
        min_length=8)
    email=forms.EmailField()#email类型

def reg(request):
    if request.method=="POST":
        print('111')
        regForm=RegForm(request.POST)
        #当所有字段都验证通过执行
        if regForm.is_valid():#当所有字段都验证成功的时候返回True
            print(regForm.cleaned_data) #字典 存放所有干净的数据
        else:
            print(regForm.errors)#字典   存放的错误字典
    #实例化
    regForm=RegForm()
    return render(request,"reg.html",locals())

说明:第一次访问reg时会创建一个空类渲染到前端,当用户输入数据时,后端进行post请求,我们利用regForm=RegForm(request.POST)给类各字段设置值。

Form组件会将符合类中的字段作为字典放到regForm.cleaned_data中,将不符合的作为字典放到regForm.errors中。

 

注意:我们给post请求添加一行返回,标红部分,可以对前端用户输入的内容做保存,即用户提交之后,输入信息还会存在

def reg(request):
    if request.method=="POST":
        print('111')
        regForm=RegForm(request.POST)
        #当所有字段都验证通过执行
        if regForm.is_valid():#当所有字段都验证成功的时候返回True
            print(regForm.cleaned_data) #字典 存放所有干净的数据
        else:
            print("error",regForm.errors.get('username'))#字典   存放的错误字典
            print("cleaned",regForm.cleaned_data)  # 字典 存放所有干净的数据
        return render(request, "reg.html", locals())
    #实例化
    regForm=RegForm()
    return render(request,"reg.html",locals())

 

我们用ie进行验证。

 

从后端可以看到不符合的字段,及报错信息

获取到错误信息我们能做什么,我们将错误信息直接渲染到reg.html中

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/reg/" method="post">
    {% csrf_token %}
{#    <p>姓名 <input type="text" name="user"></p>#}
{#    <p>密码 <input type="password" name="pwd"></p>#}
{#    <p>确认密码 <input type="password" name="repeat_pwd"></p>#}
{#    <p>邮箱 <input type="email" name="email"></p>#}
{#    <input type="submit">#}
    <p>姓名 {{ regForm.username }} <span>{{ regForm.errors.username.0 }}</span></p>
    <p>密码 {{ regForm.password }} <span>{{ regForm.errors.password.0 }}</span></p>
    <p>确认密码 {{ regForm.repeat_password }}<span>{{ regForm.errors.repeat_password.0 }}</span></p>
    <p>邮箱 {{ regForm.email }}<span>{{ regForm.errors.email.0 }}</span></p>
    <input type="submit">
</form>
</body>
</html>

说明,我们传递给reg.html的regForm对象中有errors字典,而regForm.errors.username是一个列表,所以我们使用 regForm.errors.username.0可以获取到该字段的第一个报错。

是的就是那么神奇

 

 form组件钩子

form组件判断之后可设置钩子再做一层设置,可以做全局钩子判断两次密码是否相同

class RegForm(forms.Form):
    username=forms.CharField(min_length=5,max_length=20,
                             widget=widgets.TextInput(attrs={"class": "form-control"}),
                             )#form组件引用bootstrp样式
    password=forms.CharField(min_length=5,max_length=20,
                             widget=widgets.PasswordInput(attrs={"class": "form-control"}),
                             )
    repeat_password=forms.CharField(min_length=5,max_length=20,
                                    widget=widgets.PasswordInput(attrs={"class": "form-control"}),
                                    )
    email=forms.EmailField(min_length=5,max_length=20,
                                    widget=widgets.EmailInput(attrs={"class": "form-control"}
                           ))

    valid = forms.CharField(min_length=5, max_length=20,
                             widget=widgets.TextInput(attrs={"class": "form-control"}
                                                       ))
    #钩子
    def clean_username(self):
        if not self.cleaned_data.get("username").isdigit():
#如果验证成功,需要返回
return self.cleaned_data.get("username") else: raise ValidationError("用户名不能全是数字") def clean_password(self): if len(self.cleaned_data.get("password"))>5: return self.cleaned_data.get("password") else: raise ValidationError("不能小于5") def clean(self): if self.cleaned_data.get("password")==self.cleaned_data.get("repeat_password"): return self.cleaned_data else: raise ValidationError("两次密码不一致")

 

posted @ 2017-12-06 22:44  wateligx  阅读(391)  评论(0编辑  收藏  举报