- HTML 中的表单
- 构造Django表单类
- 表单字段
- 字段属性
- Django内置插件:
- is_valid()、cleaned_data
- 二次验证
- 表单与视图处理
- GET
- POST
- is_bound
- 表单与模板
- 框架结构
- 常用表单模板
- 循环表单
- field 常用属性
- 深入学习
- 表单渲染格式
- class meta()
HTML 中的表单
- 这是 HTML 中的一个表单元素
-
- 第一个:需要提交的数据
- 第二个:提交按钮
构造Django表单类
示例:
from django import forms
class StudentLoginForm(forms.Form):
student_num = forms.CharField(
label='学号',
required=True,
max_length=11,
widget=forms.TextInput(attrs={
'class': 'form-control mb-0',
'placeholder': "请输入学号"
}),
error_messages={
'required': '学号不能为空',
'max_length': '长度不能超过50个字符',
}
)
password = forms.CharField(
label='密码',
required=True,
min_length=6,
max_length=50,
widget=forms.PasswordInput(attrs={
'class': 'form-control mb-0',
'placeholder': "请输入密码"
}),
error_messages={
'required': '用户名不能为空',
'min_length': '长度不能少于6个字符',
'max_length': '长度不能超过50个字符',
}
)
- 每一个表单类都要继承 django.forms.Form
表单字段
| Django内置字段 | Django内置字段 |
|---|---|
| BooleanField | CharField |
| ChoiceField | TypedChoiceField |
| DateField | DateTimeField |
| DecimalField | DurationField |
| EmailField | FileField |
| FilePathField | FloatField |
| ImageField | IntegerField |
| GenericlPAddressField | MultipleChoiceField |
| TypedMultipleChoiceField | NullBooleanField |
| RegexField | SlugField |
| TimeField | URLField |
| UUIDField | ComboField |
| MultiValueField | SplitDateTimeField |
| ModelChoiceField | ModelMultipleChoiceField |
password = forms.CharField(
label='密码',
required=True,
min_length=6,
max_length=50,
widget=forms.PasswordInput(attrs={
'class': 'form-control mb-0',
'placeholder': "请输入密码"
}),
error_messages={
'required': '用户名不能为空',
'min_length': '长度不能少于6个字符',
'max_length': '长度不能超过50个字符',
}
)
- label
- 用于设置说明标签
- initial
- 初始值
- required
- True:必填字段
- max_length
- 最大长度
- min_length
- 最小长度
- widget
- 指定 HTML 中的一种 input 元素类型
- 也就是自定义插件
| - | - |
|---|---|
| TextInput(Input) | NumberInput(TextInput) |
| EmailInput(TextInput) | URLInput(TextInput) |
| PasswordInput(TextInput) | HiddenInput(TextInput) |
| textarea(Widget) | DateInput(DateTimebaseInput) |
| DateTimeInput(DateTimebaseInput) | TimeInput(DateTimebaseInput) |
| CheckboxInput | Select |
| NullBooleanSelect | SelectMultiple |
| RadioSelect | CheckboxSelectMultiple |
| FileInput | ClearableFileInput |
| MultipleHiddenInput | SplitDateTimeWidget |
| SplitHiddenDateTimeWidget | SelectDateWidget |
- RadioSelect()
from django import forms gender = forms.ChoiceField( choices=((1, '男'), (2, '女'), (3, '保密')) label="性别", initial=3, widget=forms.RadioSelect() )
- Select() ---- 单选
from django import forms gender = forms.ChoiceField( choices=((1, '男'), (2, '女'), (3, '保密')) label="性别", initial=3, widget=forms.Select() )
- SelectMultiple() ---- 多选
from django import forms gender = forms.MultipleChoiceField( choices=((1, '苹果'), (2, '香蕉'), (3, '西瓜')) label="水果", initial=[1, 3], widget=forms.SelectMultiple() )
- CheckboxInput() ---- 单选
from django import forms gender = forms.ChoiceField( label="是否记住密码", initial='checked', widget=forms.CheckboxInput() )
- CheckboxSelectMultiple() ---- 多选
from django import forms gender = forms.MultipleChoiceField( choices=((1, '苹果'), (2, '香蕉'), (3, '西瓜')) label="水果", initial=[1, 3], widget=forms.CheckBoxSelectMultiple() )
- choice
choices 可以从数据库中获取:
from django import forms
class TestForm(forms.Form):
user = forms.ChoiceField(
# choices = (...)
initial=3,
widget=forms.Select()
)
def __init__(self, *args, **kwargs):
super().__init__(*args,**kwargs)
# self.fields['user'].choices=((1, '上海'), (2, '北京'),(3, '成都'))
# or
self.fields['user'].choices = models.Classes.objects.all().value_list('id', 'caption')
- error_message
- 错误信息字典
- help_text
- 帮助信息(显示在标签旁边)
- validators=[]
- 自定义验证规则
- RegexValidator 验证器
from django.forms import Form,CharField from django.core.validators import RegexValidator class TestForm(Form): user = CharField( validators=[RegexValidators(r'^[0-9]+$','请输入数字'), RegexValidators(r'^[0-9]+666$', '数字必须以 666 结尾')] )
- 自定义验证函数
import re
from django import forms
from django.core.exceptions import ValidationError
# or
# from django.forms import ValidationError
def stu_num_validate(value):
stu_num_re = re.compile(r'^20210[123][0-9]{4}$')
if not stu_num_re.match(value):
raise ValidationError('学号格式错误')
return value
class TestFrom(forms.Form):
student_num = forms.CharField(
max_length=11,
min_length=10,
# 自定义验证函数
validators=[stu_num_validator,],
widget=forms.TextInput(attrs={'class':'form-control',
'placeholder':'输入学号'}),
error_messages={
'required': '不能为空',
'min_length': '学号为10位',
}
- localize
- 是否支持本地化
- disabled
- 是否可以编辑
- label_suffix
- Label 内容后缀
is_valid()、cleaned_data
- 每个表单都有一个内置的 is_valid() 方法,验证数据是否合法
- 合法则返回 True
- 并将所有的表单数据转存到 cleaned_data 属性中(字典形式)。
- 一旦表单接收数据并验证通过,就可以从form.cleaned_data字典中读取所有的表单数据
二次验证
- 二次验证固定写法 clean_formname()
- clean_ 开头,后接变量名
class StudentLoginForm(forms.Form):
student_num = forms.CharField(...)
password = forms.CharField(...)
# 二次验证函数的名字是固定写法,以clean_开头,后面跟上字段的变量名
def clean_student_num(self):
# 通过了validators的验证之后,载进行二次验证
student_num = self.cleaned_data['student_num']
try:
# 使用student_num获取Django用户
user = User.objects.get(username=student_num)
except User.DoesNotExist:
raise forms.ValidationError('学号不存在', 'invalid')
else:
return student_num
表单与视图处理
- 构造表单类后,就可以在视图中进行实例化、处理
示例:
from django.views import View
from student.forms import StudentLoginForm
class StudentLoginView(View):
def get(self, request):
"""
显示登录页面
"""
# 实例化表单
form = StudentLoginForm()
return render(request, 'login.html', {'form': form}) # 渲染模板
def post(self, request):
"""
提交登录页面表单
"""
form = StudentLoginForm(request.POST) # 接收Form表单
# 验证表单
if form.is_valid():
student_num = request.POST['student_num'] # 获取学号
password = request.POST['password'] # 获取密码
user = authenticate(request, username=student_num, password=password) # 授权校验
if user is not None: # 校验成功,获得返回用户信息
if user.is_staff == 1:
# 如果 是管理员账户,那么跳转到管理员登录
messages.add_message(request, messages.INFO, '您好!管理员')
return redirect('/admin')
login(request, user) # 登录用户,设置登录session
request.session['uid'] = user.id # 设置用户名的session
request.session['username'] = user.student.name # 设置用户名的session
request.session['student_num'] = user.student.student_num # 设置用户名的session
return HttpResponseRedirect('/')
else:
messages.add_message(request, messages.ERROR, '用户名和密码不匹配') # 提示错误信息
return render(request, 'login.html', {'form': form}) # 渲染模板
也可写成视图函数:
def student_login(request):
if request.method == 'GET':
# 实现 Get 方法时操作
# 对应上述视图类的 get() 方法
elif request.method == 'POST':
# POST 方法时 对应的操作
# 对应上述视图类的 post() 方法
return render(request, 'login.html', {'form': form})
GET
- GET 方法请求页面时,返回空的表单,让用户可以填写数据
- POST 方法,接收表单数据,并验证;
- 如果不合法,返回一个包含先前数据的表单给前端,方便用户修改。
is_bound
- 通过表单 is_bound 属性可以获知一个表单已经绑定了数据,还是一个空表。
表单与模板框架结构
- POST方法必须添加{% csrf_token %},用于处理 csrf 安全机制
- 提交按钮自己写
- label 可以简单渲染生成: {{ field.label_tag }}
常用表单模板
{% include "form_01.html" %}
{% for field in form %}
{{ field.errors }}
{{ field.label_tag }}
{{ field }}
{% endfor %}
防止表单冲突
{% include "form_01.html" with form=comment_form %}
{% for field in comment_form %}
......
循环表单
- {% for one in *** %}..... {% endfor %} 语法
{% for field in form %}
{{ field.label_tag }}
{{ field }}
{{ field.errors }}
{% if field.help_text %}
{{ field.help_text|safe }}
{% endif %}
{% endfor %}
field 常用属性
- {{ field.属性 }}
| 属性 | 说明 |
|---|---|
| label | 字段对应的 label 属性。 |
| label_tag | 自动生成 label 标签。 |
| id_for_label | 自定义字段标签的 id 。 |
| value | 当前字段的值。 |
| html_name | 指定字段生成的 input 标签中 name 属性的值。 |
| help_text | 字段的帮助属性。 |
| errors | 包含错误信息的元素。 |
| is_hidden | 用于判断当前字段是否为隐藏字段 |
| field | 返回字段的参数列表 |
深入学习表单渲染格式
- {{ form }} 直接渲染
- {{ form.as_table }}
- 将表单渲染成一个表格元素
- 每一个输入框为一个
- 需要在模板里手动添加



