Django中表单的使用
上一篇博客我们介绍了在Django项目中使用表单的两种方式,一种是通过HTML代码实现,还有一种是使用Django自带的表单。其中使用HTML代码自己编写表单是更为常见的一种方式,对于前端页面的可控性更强。不过对于Django自带的表单,我们也通过这篇博客进行一些更深入的介绍。
处理方法
首先对Django中自带的表单使用方法进行一下简单的回顾:
1、创建forms.py文件,实现表单中的字段定义。
2、在get方法中,实例化表单对象,将表单渲染到前端页面。
例如:form = RegisterForm(), return render(request, self.TEMPLATE, {'form':form}
3、在post方法中,实例化表单对象,并将request.POST对象传递给表单。通过is_valid()对表单数据进行验证,验证通过之后,使用cleaned_data.get[subject]获取提交的数据。
例如: form = RegisterForm(request.POST)
if form.is_valid():
username = form.cleaned_data.get('username')
表单在前端自动展示
方法 | 介绍 |
---|---|
{{form}} | 直接使用 |
{{form.as_table}} | 在table标签中展示 |
{{form.as_p}} | 在p标签中展示 |
{{form.as_ul}} | 在ul标签中展示 |
{{form}}直接使用
{{form.as_table}}
{{form.as_p}}
{{form.as_ul}}
表单在前端手动展示
方法 | 介绍 |
---|---|
{{form.subject.errors }} | 展示项目验证失败时候返回的错误,如名称的s一般,是一个列表,可用for循环 |
{{form.subject.id_for_label}} | 展示项目label的名称(该标签需要手动书写label标签) |
{{form.subject.label_tag}} | 该字段的label封装在相应的HTML <label> 标签中(无需手写label标签) |
{{form.subject}} | 正式展示输入该字段的位置 |
{{form.subject.value}} | 展示默认的初始值 |
{{ form.subject.is_hidden }} | 是否是隐藏字段 true or false |
使用示例如下:
app/forms.py:
from django import forms
from django.forms import fields
class RegisterForm(forms.Form):
# max_length属性设置输入用户名的最大长度
# required = True表示不能为空
# widget属性设置输入的类型,即HTML中的<input type=''>
# initial属性设置默认的初始值
username = fields.CharField(max_length=20, required=True, initial='django')
password = fields.CharField(widget=forms.PasswordInput, initial='123456')
templates/registerForm.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="{% url 'register' %}" method="post">
{% csrf_token %}
<div>
<label for="{{form.username.id_for_label}}">Username</label>
{{form.username}}
{{form.username.value}}
{{form.username.is_hidden}}
</div>
<div>
<label for="{{form.password.id_for_label}}">Password</label>
{{form.password}}
{{form.password.value}}
{{form.password.is_hidden}}
</div>
<input type="submit" value="提交">
</form>
</body>
</html>
启动服务,进行访问如下:
for循环进行手动展示
在Django自带的表单中,我们还可以通过for循环的方式进行表单的手动展示。使用方式如下:
templates/registerForm.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="{% url 'register' %}" method="post">
{% csrf_token %}
{% for item in form %}
<div>
<label for="{{item.id_for_label}}">{{item.label}}</label>
{{item}}
</div>
{% endfor %}
<input type="submit" value="提交">
</form>
</body>
</html>
在app/forms.py中我们需要为字段添加上label属性:
from django import forms
from django.forms import fields
class RegisterForm(forms.Form):
# max_length属性设置输入用户名的最大长度
# required = True表示不能为空
# widget属性设置输入的类型,即HTML中的<input type=''>
# initial属性设置默认的初始值
username = fields.CharField(max_length=5,
required=True,
initial='django',
label='用户名')
password = fields.CharField(widget=forms.PasswordInput,
initial='123456',
label='密码')
启动服务,进行访问如下:
内置表单字段类型介绍
内置表单字段属性介绍
内置表单的字段属性,设置之后可以在前端为我们进行一个简单的验证环节,满足指定要求才能进行提交。例如,我们设置如下:
from django import forms
from django.forms import fields
class RegisterForm(forms.Form):
# max_length属性设置输入用户名的最大长度
# required = True表示不能为空
# widget属性设置输入的类型,即HTML中的<input type=''>
# initial属性设置默认的初始值
username = fields.CharField(min_length=3,
max_length=6,
required=True,
initial='django',
label='用户名')
password = fields.CharField(widget=forms.PasswordInput,
initial='123456',
label='密码')
启动服务进行访问,字段的长度如果不符合要求,点击“提交”按钮,会提示错误信息。
后端自定义验证规则
上面展示了通过字段的属性设置进行简单的前端验证,如果我们需要进行更加复杂的自定义的验证规则,可以在后端进行实现。
app/forms.py中我们在表单类下实现clean函数:
import re
class RegisterForm(forms.Form):
# max_length属性设置输入用户名的最大长度
# required = True表示不能为空
# widget属性设置输入的类型,即HTML中的<input type=''>
# initial属性设置默认的初始值
username = fields.CharField(max_length=100,
required=True,
initial='django',
label='用户名')
password = fields.CharField(widget=forms.PasswordInput,
initial='123456',
label='密码')
# clean函数中进行全局验证,即所有字段的验证都可以在这里实现
def clean(self):
username = self.cleaned_data.get('username','')
password = self.cleaned_data.get('password','')
if len(username) > 8:
print('用户名验证环节')
raise forms.ValidationError('用户名长度不能超过8!')
if len(re.findall(r'[a-zA-Z]', password)) == 0:
print('密码验证环节')
raise forms.ValidationError('密码中必须包含字母!')
在clean函数中我们对username和password字段进行了一些限制,然后在app/views.py中我们需要进行一些修改:
from django.shortcuts import render, redirect
from django.views.generic import View
from .forms import RegisterForm
class Register(View):
TEMPLATE = 'registerForm.html'
def get(self, request):
form = RegisterForm()
return render(request, self.TEMPLATE, {'form':form})
def post(self, request):
form = RegisterForm(request.POST)
if form.is_valid():
# is_valid()函数判断是否通过后端验证;
username = form.cleaned_data.get('username')
password = form.cleaned_data.get('password')
print('username: ', username)
print('password: ', password)
return redirect('/register')
else:
# 如果没有通过后端验证,在前端页面中我们可以通过form.non_field_errors进行显示
return render(request, self.TEMPLATE, {'form':form})
前端页面templates/registerForm.html文件:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
<form action="{% url 'register' %}" method="post">
{% csrf_token %}
{% for item in form %}
<div>
<label for="{{item.id_for_label}}">{{item.label}}</label>
{{item}}
</div>
{% endfor %}
<span>{{form.non_field_errors}}</span>
<input type="submit" value="提交">
</form>
</body>
</html>
启动服务进行访问:
我们也可以为每个字段都实现一个单独的函数定义该字段的验证规则,例如我们实现单独的函数对username进行验证:
app/forms.py:
from django import forms
from django.forms import fields
import re
class RegisterForm(forms.Form):
# max_length属性设置输入用户名的最大长度
# required = True表示不能为空
# widget属性设置输入的类型,即HTML中的<input type=''>
# initial属性设置默认的初始值
username = fields.CharField(max_length=100,
required=True,
initial='django',
label='用户名')
password = fields.CharField(widget=forms.PasswordInput,
initial='123456',
label='密码')
# clean函数中进行全局验证,即所有字段的验证都可以在这里实现
def clean(self):
password = self.cleaned_data.get('password','')
if len(re.findall(r'[a-zA-Z]', password)) == 0:
print('密码验证环节')
raise forms.ValidationError('密码中必须包含字母!')
def clean_username(self):
username = self.cleaned_data.get('username', '')
if len(username) > 8:
print('用户名验证环节')
raise forms.ValidationError('用户名长度不能超过8!')
然后在前端页面中,我们就可以通过{{form.subject.errors}}显示错误信息:
此时,启动服务访问如下:
参考资料
https://coding.imooc.com/class/393.html