1. Form組件的功能
對用戶提交表單數據進行校驗、保留上次輸入內容。
2. 數據校驗
Form組件對Form表單的方式提交的數據進行校驗:
login.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登錄</title>
<link rel="stylesheet" href="/static/css/bootstrap.min.css">
</head>
<body>
<div class="container" style="margin-top: 10px">
<div class="row">
<div class="col-md-4 col-md-offset-4">
<div class="panel panel-primary">
<div class="panel-heading">
登錄
</div>
<div class="panel-body">
<form action="/login.html/" method="POST" name="loginForm">
<div class="form-group">
<label for="name">用戶名</label>
<input type="text" class="form-control" name="name" placeholder="請輸入用戶名">
<div style="color: red;font-weight: bold">{{ obj.errors.name.0 }}</div>
</div>
<div class="form-group">
<label for="">密碼</label>
<input type="password" class="form-control" name="pwd" placeholder="請輸入密碼">
<div style="color: red;font-weight: bold">{{ obj.errors.pwd.0 }}</div>
</div>
{% csrf_token %}
<button type="submit" class="btn btn-primary">登錄</button>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
class LoginForm(Form):
name = fields.CharField(
required=True,
min_length=6,
max_length=20,
error_messages={
'required': '用戶名不能爲空!',
'min_length': '用戶名長度不能小於6!',
'max_length': '用戶名長度不能大於20!'
}
)
pwd = fields.CharField(
required=True,
min_length=6,
max_length=20,
error_messages={
'required': '密碼不能爲空!',
'min_length': '密碼長度不能小於6!',
'max_length': '密碼長度不能大於20!'
}
)
def login(request):
if request.method == 'GET':
return render(request, 'login.html')
else:
obj = LoginForm(request.POST)
"""
1、LoginForm實例化時
self.field={'name':正則表達式,'pwd':正則表達式}
2、循環self.field
for k,v in self.field.items():
input_value = request.POST.get(k)
正則表達式和input_value進行匹配
"""
if obj.is_valid():
# 校驗通過的數據
print(obj.cleaned_data)
else:
print(obj.errors, type(obj.errors)) # <class 'django.forms.utils.ErrorDict'>
"""
<ul class="errorlist">
<li>name
<ul class="errorlist">
<li>用戶名不能爲空</li>
</ul>
</li>
<li>pwd
<ul class="errorlist">
<li>用戶名不能爲空</li>
</ul>
</li>
</ul>
"""
return render(request, 'login.html', {'obj': obj})
上面是Form組件校驗以Form表單的方式的提交數據,下面是以AJAX的方式提交數據:
login.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>登錄</title>
<link rel="stylesheet" href="../static/css/bootstrap.min.css">
</head>
<body>
<div class="container" style="margin-top: 10px">
<div class="row">
<div class="col-md-4 col-md-offset-4">
<div class="panel panel-primary">
<div class="panel-heading">
登錄
</div>
<div class="panel-body">
<form id="form" action="" method="POST" name="loginForm" novalidate>
<div class="form-group">
<label for="name">用戶名</label>
<input type="text" class="form-control" name="name" placeholder="請輸入用戶名">
<div style="color: red;font-weight: bold">{{ obj.errors.name.0 }}</div>
</div>
<div class="form-group">
<label for="">密碼</label>
<input type="password" class="form-control" name="pwd" placeholder="請輸入密碼">
<div style="color: red;font-weight: bold">{{ obj.errors.pwd.0 }}</div>
</div>
<div class="form-group">
<label for="">郵箱</label>
<input type="email" class="form-control" name="email" placeholder="請輸入密碼">
<div style="color: red;font-weight: bold">{{ obj.errors.email.0 }}</div>
</div>
<div class="form-group">
<label for="">手機號</label>
<input type="text" class="form-control" name="phone" placeholder="請輸入密碼">
<div style="color: red;font-weight: bold">{{ obj.errors.phone.0 }}</div>
</div>
{% csrf_token %}
<button id="loginBtn" type="button" class="btn btn-primary">登錄</button>
</form>
</div>
</div>
</div>
</div>
</div>
</body>
<script src="../static/js/jquery-3.5.1.min.js"></script>
<script>
$(function () {
ajaxLogin();
})
function ajaxLogin() {
$('#loginBtn').click(function () {
var formData = $('#form').serialize();//會忽略字段左右的空格
console.log(formData)//name=thanlon&pwd=123456&[email protected]&phone=18523332005&csrfmiddlewaretoken=xxx
$.ajax({
url: '/login.html/',
type: 'post',
data: formData,
dataType: 'json',
success: function (arg) {
console.log(arg);//{"status": 0, "msg": null}
if (arg.status) {
//location.href = 'https://www.baidu.com'
} else {
//清除之前的錯誤提示信息
$('.clearTag').remove();
console.log(arg.msg)//對象類型
$.each(arg.msg, function (index, value) {
/**
* alert(index);//錯誤字段,pwd
* alert(value);//錯誤消息,如This field is required.
* alert(typeof (index)) //string
* alert(typeof (value))//object
* alert(value[0])
*/
var tag = document.createElement('span');
tag.innerHTML = value[0];
tag.className = 'clearTag';
$('#form').find('input[name="' + index + '"]').after(tag);
})
}
}
})
})
}
</script>
</html>
views.py:
from django.forms import Form, fields
from django.shortcuts import render, HttpResponse
from app01 import models
import json
class LoginForm(Form):
name = fields.CharField()
pwd = fields.CharField()
email = fields.EmailField()
phone = fields.RegexField('185\d+')
def ajax_login(request):
if request.method=='GET':
return render(request,'login.html')
ret = {'status': True, 'msg': None}
print(type(json.dumps(ret))) # <class 'str'>
obj = LoginForm(request.POST)
if obj.is_valid():
print(obj.cleaned_data)#{'name': 'thanlon', 'pwd': '123456', 'email': '[email protected]', 'phone': '18523332005'}
else:
print(obj.errors) # obj.errors是對象
ret['status'] = False
ret['msg'] = obj.errors
return HttpResponse(json.dumps(ret)) # <class 'str'>
AJAX僅用來驗證功能,Form可以驗證功能也可以生成HTML標籤。
3. 常用字段和參數
Field:
required = True, # 是否允許爲空
label = None, # 用於生成Label標籤
initial = None, # 初始值
help_text = '', # 幫助信息(在標籤旁邊顯示)
error_messages = {}, # 錯誤信息{'invalid':'格式錯誤'}
show_hidden_initial = None, # 是否在當前插件後面再加上一個隱藏的且具有默認值的插件(可用於檢驗兩次輸入是否一致)
validators = [], # 自定義驗證規則
localize = False, # 是否支持本地化
disabled = False, # 是否可以編輯
label_suffix = None, # Label內容後綴
widget = None, # HTML插件
CharField類和IntegerField 類都繼承Field類,但是除了具有Field中的所有屬性之外還有其它屬性:
CharField(Field):
min_length = None,
max_length = None,
strip = True, # 是否移除空白
IntegerField(Field):
min_length = None,
max_length = None,
DecimalField(IntegerField):
max_value=None, # 最大值
min_value=None, # 最小值
max_digits=None, # 總長度
BaseTemporalField(Field)
input_formats=None, # 時間格式化
BaseTemporalField(Field)
input_formats=None, # 時間格式化
DateField(BaseTemporalField): # 格式:2020-10-12
TimeField(BaseTemporalField): # 格式:12:50
DateTimeField(BaseTemporalField): # 格式:2020-10-12 12:50
DurationField(Field): # 時間間隔:%d %H:%M:%S.%f
RegexField(CharField):
regex='185\d+',
max_length=None,
min_length=None,
error_messages={}
EmailField(CharField)
URLField(CharField)
SlugField(CharField)
GenericIPAddressField(CharField)
4. 保留上次輸入內容
Form表單的方式提交數據,頁面會刷新會失去提交的內容。AJAX方式提交時頁面不刷新,上次輸入內容自動保存。使用Form表單提交數據保存上次輸入的內容也是可以實現的,需要應用到Form組件提供的第二個功能 生成HTML標籤
。只需要在 input 框中加入驗證通過的數據 obj.cleaned_data
:
views.py:
class LoginForm(Form):
name = fields.CharField(
label='用戶名',
)
pwd = fields.CharField(
label='密碼',
)
email = fields.EmailField(
label='郵箱'
)
phone = fields.RegexField(
label='手機號',
regex='185\d+',
)
def ajax_login(request):
if request.method == 'GET':
obj = LoginForm()
return render(request, 'login.html',{'obj': obj})
else:
obj = LoginForm(request.POST)
if obj.is_valid():
print(obj.cleaned_data)
else:
print(obj.errors)
return render(request, 'login.html', {'obj': obj})
login.html:
...
<form id="form" action="" method="POST" name="loginForm" novalidate>
<!--{{ obj.as_p }}-->
<div class="form-group">
{{ obj.name.label }}
<input type="text" class="form-control" name="name" placeholder="請輸入用戶名" value="{{ obj.cleaned_data.name }}">
<div style="color: red;font-weight: bold">{{ obj.errors.name.0 }}</div>
</div>
<div class="form-group">
{{ obj.pwd.label }}
<input type="password" class="form-control" name="pwd" placeholder="請輸入密碼" value="{{ obj.cleaned_data.pwd }}">
<div style="color: red;font-weight: bold">{{ obj.errors.pwd.0 }}</div>
</div>
<div class="form-group">
{{ obj.email.label }}
<input type="email" class="form-control" name="email" placeholder="請輸入郵箱" value="{{ obj.cleaned_data.email }}">
<div style="color: red;font-weight: bold">{{ obj.errors.email.0 }}</div>
</div>
<div class="form-group">
{{ obj.phone.label }}
<input type="text" class="form-control" name="phone" placeholder="請輸入手機號" value="{{ obj.cleaned_data.phone }}">
<div style="color: red;font-weight: bold">{{ obj.errors.phone.0 }}</div>
</div>
{% csrf_token %}
<button id="loginBtn" type="submit" class="btn btn-primary">登錄</button>
</form>
...
上一次驗證通過的數據纔會被保存: