有时时候我们需要使用get,post,put等方式在前台HTML页面提交一些数据到后台处理例 ;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
<!DOCTYPE html>
<html lang= "en" >
<head>
<meta charset= "UTF-8" >
<title>Form</title>
</head>
<body>
<div>
<form action= "url" method= "post" enctype= "multipart/form-data" >{% csrf_token %}
<input type= "text" name= "username" />
<input type= "password" name= "password" />
<input type= "submit" value= "submit" />
</form>
</div>
</body>
|
前端提交后台获取:
1
2
3
4
5
6
7
|
from django.shortcuts import render,HttpResponse,redirect
from app01 import models
def Login(request):
if request.method == "POST" :
username = request.POST.get( "username" )
password = request.POST.get( "password" )
return HttpResponse( "Hello,%s" %(username))
|
这样就完成了基本的功能,基本上可以用了。
但是,如果用户输入并未按照要求(比如手机号要输数据11位长度,密码的复杂度等),还有就是提交后再回来已经输入的数据也会没了
当然如果我们手动将输入之后的数据在 views 中都获取到再传递到网页,这样是可行的,但是很不方便,所以 Django 提供了更简单易用的 forms 来解决验证等这一系列的问题
,在这里不得不提Django的插件库真的很强大,简单易扩展,上面的内容只是引进为什么要使用form,下面着重记录django form的使用
二.form表单验证应用
需要在django的APP中新建一个模块form.py,具体内容如下
1
2
3
4
5
6
7
8
|
class RegisterForm(forms.Form):
email = forms.EmailField(required=True,
error_messages={ 'required' : "邮箱不能为空" })
password = forms.CharField(max_length=120,
min_length=6,
required=True,
error_messages={ 'required' : "密码不能为空" })
invite_code = forms.CharField(required=True,error_messages={ 'required' : "验证码不能为空" })
|
前端页面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<!DOCTYPE html>
<html lang= "en" >
<head>
<meta charset= "UTF-8" >
<title>register</title>
</head>
<body>
<div>
<form action= "url" method= "post" enctype= "multipart/form-data" >
<input type= "text" name= "username" />
<input type= "password" name= "password" />
<input type= "text" name= "code" />
<input type= "submit" value= "submit" />
</form>
</div>
</body>
|
后台views处理
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
def register(request):
if request.method == "POST" :
f = Reg_Form(request.POST)
if f.is_valid():
user = f.cleaned_data[ "username" ]
pwd = f.cleaned_data[ "password" ]
code = f.cleaned_data[ "code" ]
res_code = request.session.get( "code" , None)
result = models.UserInfo.objects.filter(user__exact=user,pwd__exact=pwd)
if code.upper() == res_code.upper() and result:
models.UserInfo.objects.filter(user__exact=user).update(status=1)
request.session[ "user" ] = user
return redirect( "/home" )
else :
return render(request, "register.html" , { "error" : f.errors, "form" : f}) else : return render(request, "register.html" )
|
Reg_Form(request.POST) 使用form类来处理提交的数据来验证数据的合法性,is_valid()合法后的逻辑处理,验证后的数据保存在实例化后返回的cleaned_data中,
cleaned_data是个字典的数据格式,错误信息保存在form.errors中比如说想在views中查看所有报错信息print(f.errors),如果只想看用户的可以
1
|
print (form.errors[ 'username' ][0])
|
错误信息我们可以通过 模板渲染回前端页面,例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<form action= "/form/" method= "POST" >
{% csrf_token %}
<div class = "input-group" >
{#接收后台传过来的form对象,自动生成input标签#}
{{ form.user }}
{#从后台传过来的error是字典,直接{{ error.user.0 }}呈现错误信息#}
{#如果后台返回了错误信息,将错误信息放入span标签,在页面显示,否则不显示#}
{% if error.username.0 %}
<span>{{ error.userusername.0 }}</span>
{% endif %}
</div>
<div class = "input-group" >
{{ form.password }}
{% if error.pwd.0 %}
<span>{{ error.password .0 }}</span>
{% endif %}
</div>
<div>
<input type= "submit" value= "提交" />
</div>
</form>
|
三.自生成input框
Form类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
class RegisterForm(forms.Form):
style = 'form-control input-lg'
phone = forms.CharField(widget=forms.TextInput(attrs={ 'class' : style,
'name' : 'title' })),
required=True,
error_messages={ 'required' : ugettext_lazy( '*Required' )})
code = forms.CharField(widget=forms.NumberInput(attrs={ 'placeholder' : '验证码' ,
'class' : style}),
min_length=4,
max_length=4,
required=True,
error_messages={ 'required' : ugettext_lazy( '*Required' )})
password = forms.CharField(widget=forms.PasswordInput(attrs={ 'placeholder' : '请输入密码' ,
'class' : style}),
min_length=6,
required=True,
error_messages={ 'required' : ugettext_lazy( '*Required' )})
|
views
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
def register(request):
if request.method == "POST" :
f = RegisterForm(request.POST)
if f.is_valid():
user = f.cleaned_data[ "username" ]
pwd = f.cleaned_data[ "password" ]
code = f.cleaned_data[ "code" ]
res_code = request.session.get( "CheckCode" , None)
result = models.UserInfo.objects.filter(user__exact=user,pwd__exact=pwd)
if code.upper() == res_code.upper() and result:
models.UserInfo.objects.filter(user__exact=user).update(status=1)
request.session[ "user" ] = user
return redirect( "/home" )
else :
return render(request, "login.html" , { "error" : f.errors, "form" : f})
else :
return render(request, "login.html" , { "error" : f.errors, "form" : f})
else :
# 如果不是post提交数据,就不传参数创建对象,并将对象返回给前台,直接生成input标签,内容为空
f = Log_Form()
return render(request, "login.html" , { "form" : f})
|
前端页面
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
<body>
<form action= "/form/" method= "POST" >
{% csrf_token %}
<div class= "input-group" >
{ # 接收后台传过来的form对象,自动生成input标签#}
{{ form.user }}
{ # 从后台传过来的error是字典,直接{{ error.user.0 }}呈现错误信息#}
{ # 如果后台返回了错误信息,将错误信息放入span标签,在页面显示,否则不显示#}
<div class= "input-group" >
{{ form.email }}
{% if error.email.0 %}
<span>{{ error.email.0 }}</span>
{% endif %}
</div>
<div class= "input-group" >
{{ form.password }}
{% if error.password.0 %}
<span>{{ error.password.0 }}</span>
{% endif %}
</div>
<div class= "input-group" >
{{ form.code }}
{% if error.book_type.0 %}
<span>{{ error.code.0 }}</span>
{% endif %}
</div>
<div>
<input type= "submit" value= "提交" />
</div>
</form>
</body>
</html>
|
四.Form验证完善
https://docs.djangoproject.com/en/dev/ref/forms/validation/
form验证的运行顺序是init,clean,validte,save
其中clean和validate会在form.is_valid()方法中被先后调用
clean等步骤遇到的异常:Exception Value: argument of type 'NoneType' is not iterable.
可能是cleaned_data中某个字段值应该是个列表,实际上却是空值。
clean方法重写时一定不要忘了return cleaned_data
这样重写可以使用户提交的数据在form类中执行检测完后返回数据给用户,数据合法后进行逻辑处理,不需要再进行处理返回用户,更方便更合理
补充:
5.form的四种初始化方式
①实例化oneform(initial={'onefield':value})
②定义字段时给初始化值oneformfield = forms.CharField(initial=value)
③重写Form类的__init__()方法:self.fields['onefield'].initial = value
④当给form传参instanse(即oneform(instanse=onemodel_instance))时,前三种初始化方法会全部失效,即使重写__init__时,先调用父类的__init__再使用方法③,仍然无效(不是很爽)。
这时想重新初始化字段值只能在__init__()里 self.initial['title'] = value,直接对Form类的initial属性字典赋值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
from django import forms
class RegisterForm(forms.Form):
email = forms.EmailField(required = True ,
error_messages = { 'required' : "邮箱不能为空" })
password = forms.CharField(max_length = 120 ,
min_length = 6 ,
required = True ,
error_messages = { 'required' : "密码不能为空" })
invite_code = forms.CharField(required = True ,error_messages = { 'required' : "验证码不能为空" })
def clean( self ):
# 用户名
try :
email = self .cleaned_data[ 'email' ]
except Exception as e:
raise forms.ValidationError(u "注册账号需为邮箱格式" )
# 验证邮箱
user = User.objects. filter (username = email)
if user: # 邮箱已经被注册了
raise forms.ValidationError(u "邮箱已被注册" )
# 密码
try :
password = self .cleaned_data[ 'password' ]
except Exception as e:
print ( 'except: ' + str (e))
raise forms.ValidationError(u "请输入至少6位密码" )
return self .cleaned_data
|
以上所述是小编给大家介绍的Python中使用django form表单验证的方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!
原文链接:http://www.cnblogs.com/jl-bai/p/6288218.html