慕课网-Django入门到进阶-更适合Python小白的系统课程-第5章Django中的Form表单的使用-5-2form表单验证与前端显示方法
第5章 Django 中的 Form 表单的使用
5-2 Form 表单验证与前端显示方法
处理方法
1.表单只处理 get 和 post
2.在 get 中,实例化表单对象,将 form 表单渲染到模板
3.在 post 中,实例化表单对象,并将 request.POST 对象传给表单
4.Get -> form = Auth()
5.Post -> form = Auth(request.POST),通过 is_valid() 对数据进行验证,当验证通过后,可以通过 cleaned_data[subject] 获取输入的值
表单在前端自动展示的方法
| 方法 | 介绍 |
| {{form}} | 直接使用 |
| {{form.as_table}} | 他会在你的 table 标签中展示 |
| {{form.as_p}} | 他会生成在 p 标签内 |
| {{form.as_ul}} | 他会在你的 ul 中以 li 形式展示 |
代码演示
<p><label for="id_subject">Subject:</label><input type="text" name="subject" maxlength="100" required /></p> <p><label for="id_message">Message:</label><textarea name="message" id="id_message" required /></textarea></p> <p><label for="id_sender">Sender:</label><input type="email" name="sender" id="sender" required /></p> <p><label for="id_cc_myself">Cc myself:</label><input type="checkbox" name="cc_myself" id="id_cc_myself" /></p>
表单在前端手动展示的方法
| 方法 | 介绍 |
| {{form.subject.errors}} | 展示项目验证失败时候返回的错误,如名称的 s 一般,他是一个列表,可用 for 循环 |
| {{form.subject.id_for_label}} | 展示项目 label 的名称(该标签需要手动书写 label 标签) |
| {{form.subject.label_tag}} | 该字段的 label 封装在相应的 HTML <label> 标签中 |
| {{form.subject}} | 正式展示输入该字段的位置 |
| {{form.subject.value}} | 展示默认的初始值 |
| {{form.subject.is_hidden}} | 是否是隐藏字段 true or false |
代码演示
<div class="fieldWrapper">
{{form.subject.errors}}
<label for="{{form.subject.id_for_label}}">Email subject:</label>
{{form.subject}}
</div>
For 循环展示错误
{% if form.subject.errors %}
<ol>
{% for error in form.subject.errors %}
<li><strong>{{ error|escape }}</strong></li>
{% endfor %}
</ol>
{% endif %}
内置表单字段类型介绍
| 类型名称 | 介绍 |
| CharField | 文本类型 |
| EmailField | 验证是否是有效的 email 格式 |
| URLField | 验证是否是有效的 url 地址 |
| GenericIPAddressField | 验证 ip 类型 |
| TimeField | 验证是否为 datetime.time 或指定格式的字符串 |
| DateField | 验证日期格式,通过参数 input_formats 定义日期格式 |
| ChoiceField | 选择类型,通过参数 choices 设置内容 |
| BooleanField | 复选框,当 required=True 时默认勾选 |
| IntegerField | 验证值是否是整数 |
| FloatField | 验证值是否是浮点类型 |
| FileField | 文件上传,allow_empty_file 设置是否可为空 |
| ImageField | 验证上传的文件是否是图片 |
代码演示
# forms 中导入 fields 中的对象 from django import forms # 字段来源于此 form django.forms import fields
内置表单字段属性介绍
| 属性名称 | 介绍 |
| required | 是否必填,默认为 True |
| widget | 设置 input 的 type 样式,更多类型 fields.widget |
| label | 设置标签名 |
| initial | 设置初始值 |
| localize | 是否支持时间本地化,时区不同时显示响应的时间 |
| disabled | 是否可编辑 |
| error_messages | 设置错误信息,字典类型,对属性错误进行说明 |
| max_length | 设置最大长度 |
| min_length | 设置最小长度 |
| validators | 自定义验证规则,列表,内容是自定义的验证函数 |
代码演示
fields.CharField(max_length=50, required=True, widget=forms.widget.PasswordInput, error_messages={'required':'内容不能为空'}, label='密码')
实例
1.在项目 form 下目录 templates,修改文件 regist.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>regist</title>
</head>
<body>
<form action="{% url 'regist' %}" method="post">
{% csrf_token %}
{% for item in form %}
<label for="{{item.id_for_label}}">{{item.label}}</label>
{{item}}
<p>{{item.errors.as_text}}</p>
{% endfor %}
<span>{{form.non_field_errors}}</span>
<!--<label>用户名</label><input type="text" name="username" placeholder="用户名" /><br/>-->
<!--<label>密码</label><input type="password" name="password" placeholder="密码" /><br/>-->
<input type="submit" value="提交" />
</form>
</body>
</html>
2.在项目 form 下目录 app,修改文件 forms.py
from django import forms
from django.forms import fields
class Auth(forms.Form):
username = fields.CharField(max_length=18, required=True, label="username")
password = fields.CharField(widget=forms.PasswordInput, label="password")
3.测试
4.在项目 form 下目录 templates,修改文件 regist.html,添加了 div
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>regist</title>
</head>
<body>
<form action="{% url 'regist' %}" method="post">
{% csrf_token %}
{% for item in form %}
<div>
<label for="{{item.id_for_label}}">{{item.label}}</label>
{{item}}
<p>{{item.errors.as_text}}</p>
</div>
{% endfor %}
<span>{{form.non_field_errors}}</span>
<!--<label>用户名</label><input type="text" name="username" placeholder="用户名" /><br/>-->
<!--<label>密码</label><input type="password" name="password" placeholder="密码" /><br/>-->
<input type="submit" value="提交" />
</form>
</body>
</html>
5.在项目 form 下目录 app,修改文件 forms.py
from django import forms
from django.forms import fields
class Auth(forms.Form):
username = fields.CharField(
max_length=18,
min_length=3,
required=True,
label="用户名",
widget=forms.TextInput(attrs={'placeholder':'最大不能超过18字符'}),
# error_messages={'max_length':'最大不能超过18字符!'}
)
password = fields.CharField(
widget=forms.PasswordInput(attrs={'placeholder':'请输入密码'}),
label="密码",
required=True,
min_length=10,
error_messages={'min_length':'最小不能低于10个字符'}
)
6.测试

7.在项目 form 下目录 app,修改文件 forms.py,全体验证
from django import forms
from django.forms import fields
class Auth(forms.Form):
username = fields.CharField(
max_length=18,
min_length=3,
required=True,
label="用户名",
widget=forms.TextInput(attrs={'placeholder':'最大不能超过18字符'}),
error_messages={'max_length':'最大不能超过18字符!'}
)
password = fields.CharField(
widget=forms.PasswordInput(attrs={'placeholder':'请输入密码'}),
label="密码",
required=True,
min_length=10,
error_messages={'min_length':'最小不能低于10个字符'}
)
def clean(self):
username = self.cleaned_data.get('username', '')
password = self.cleaned_data.get('password', '')
if not username:
raise forms.ValidationError('用户名不可以为空!')
if len(username) > 10:
raise forms.ValidationError('用户名最大不能超过10')
if not password:
raise forms.ValidationError('密码不可以为空!')
8.在项目 form 下目录 app,修改文件 views.py
from django.shortcuts import render, redirect
from django.views.generic import View
from .forms import Auth
class Regist(View):
TEMPLATE = 'regist.html'
def get(self, request):
form = Auth()
return render(request, self.TEMPLATE, {'form': form})
def post(self, request):
# username = request.POST.get('username')
# password = request.POST.get('password')
form = Auth(request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
print('username:', username)
print('password', password)
else:
return render(request, self.TEMPLATE, {'form':form})
return redirect('/regist')
9.在项目 form 下目录 templates,修改文件 regist.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>regist</title>
</head>
<body>
<form action="{% url 'regist' %}" method="post">
{% csrf_token %}
{% for item in form %}
<div>
<label for="{{item.id_for_label}}">{{item.label}}</label>
{{item}}
<p>{{item.errors.as_text}}</p>
</div>
{% endfor %}
<span>{{form.non_field_errors.as_text}}</span><br/>
<!--<label>用户名</label><input type="text" name="username" placeholder="用户名" /><br/>-->
<!--<label>密码</label><input type="password" name="password" placeholder="密码" /><br/>-->
<input type="submit" value="提交" />
</form>
</body>
</html>
10.测试

11.在项目 form 下目录 app,修改文件 forms.py,单独验证
from django import forms
from django.forms import fields
class Auth(forms.Form):
username = fields.CharField(
max_length=18,
min_length=3,
required=True,
label="用户名",
widget=forms.TextInput(attrs={'placeholder':'最大不能超过18字符'}),
error_messages={'max_length':'最大不能超过18字符!'}
)
password = fields.CharField(
widget=forms.PasswordInput(attrs={'placeholder':'请输入密码'}),
label="密码",
required=True,
min_length=10,
error_messages={'min_length':'最小不能低于10个字符'}
)
def clean(self):
password = self.cleaned_data.get('password', '')
if not password:
raise forms.ValidationError('密码不可以为空!')
def clean_username(self):
username = self.cleaned_data.get('username', '')
if len(username) > 18:
raise forms.ValidationError('用户名最大不能超过18')
return username
12.测试

13.在项目 form 下目录 app,修改文件 views.py,使用 reverse 反转 URL
from django.shortcuts import render, redirect, reverse
from django.views.generic import View
from .forms import Auth
class Regist(View):
TEMPLATE = 'regist.html'
def get(self, request):
form = Auth()
return render(request, self.TEMPLATE, {'form': form})
def post(self, request):
# username = request.POST.get('username')
# password = request.POST.get('password')
form = Auth(request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
print('username:', username)
print('password', password)
else:
return render(request, self.TEMPLATE, {'form':form})
return redirect(reverse('regist'))
posted on 2020-02-06 09:10 herisson_pan 阅读(6) 评论(0) 收藏 举报
浙公网安备 33010602011771号