【图书介绍】《Django 5企业级Web应用开发实战(视频教学版)》_django 5企业级web应用开发实战(视频教学版)-CSDN博客
《Django 5企业级Web应用开发实战(视频教学版)》(王金柱)【摘要 书评 试读】- 京东图书 (jd.com)
本节主要介绍一个使用Django框架表单构建Web应用的实例。使用Django框架表单实现内容提交与传统HTML表单方式不同,主要是通过表单Form类来完成的。
6.2.1 使用Form类构建表单
Django框架内置的Form类可以自动生成模板表单,这样就无须以手动方式在HTML模板中定义表单了。Form类就是表单类,继承自django.forms.Form模块,适用于构建Django框架表单的基础类。
下面,我们通过Form类构建一个简单的、用于提交“用户信息”的表单。使用Form类定义表单,通常需要在App中新建一个表单模块(forms.py),该模块一般要与视图模块(views.py)和模型模块(models.py)放置于同一级别目录下。
表单模块的具体代码如下:
【代码6-2】(详见源代码FormSite项目的formapp/forms.py文件)
01 from django import forms
02
03 # Form类
04 class UserInfoForm(forms.Form):
05 username = forms.CharField(label='Your name', max_length=32)
06 dep = forms.CharField(label='Your department', max_length=8)
07 email = forms.EmailField(label='Your email', max_length=64)
【代码分析】
在第01行代码中,通过import关键字引入forms模块。
在第04~07行代码中,通过class定义表单类UserInfoForm,其中内置了相关的表单字段。注意,所有自定义的表单类均继承自forms.Form类。关于表单字段的详细说明如下:
- 在第05行代码中,通过CharField字段类型定义了一个表单字段username,对应于HTML表单<form>标签中的“用户名”文本输入框。
- 在第06行代码中,通过CharField字段类型定义了一个表单字段dep,对应于HTML表单<form>标签中的“部门”文本输入框。
- 在第07行代码中,通过EmailField字段类型定义了一个表单字段email,对应于HTML表单<form>标签中的“电子邮件”输入框。
另外,这段Form类代码没有定义提交按钮,需要设计人员自行在HTML模板表单中进行添加。这样做的好处是,设计人员可以在HTML模板中为表单定义脚本行为、添加CSS样式以及嵌入第三方框架。
6.2.2 视图处理
在Django框架表单中,Form类的渲染工作要求视图来处理。在视图中,需要实例化定义好的Form类,并进行必要的表单验证工作。
每个Django框架表单的实例都有一个内置的is_valid()方法,用来验证接收的数据是否合法。如果所有数据都合法,那么该方法将返回True,并将所有的表单数据转存到它的一个叫作“cleaned_data”的属性中,该属性是一个字典类型数据。
Django框架表单的实例化代码一般放在views.py中,views.py视图文件与forms.py表单文件一般处于同一级目录。表单类UserInfoForm的实例化代码如下:
【代码6-3】(详见源代码FormSite项目的formapp/views.py文件)
01 from .forms import UserInfoForm
02 # 创建表单视图
03 def userinfo(request):
04 # 如果这是一个POST请求,那么我们需要处理表单数据
05 if request.method == 'POST':
06 #创建一个表单实例并用请求中的数据填充
07 form = UserInfoForm(request.POST)
08 # 检查表单是否有效
09 if form.is_valid():
10 # 按照要求处理表单中的数据
11 context = {}
12 context['uname'] = request.POST['username']
13 context['udep'] = request.POST['dep']
14 context['uemail'] = request.POST['email']
15 # 重定向到一个新的URL
16 return render(request, 'show_info.html', {'userinfo': context})
17 # 如果是GET(或其他任何方法),我们将创建一个空白表单
18 else:
19 form = UserInfoForm()
20 # 在HTML模板中渲染表单
21 return render(request, 'userinfo.html', {'form': form})
【代码分析】
在第01行代码中,通过import关键字引入UserInfoForm表单类。
在第03~21行代码中,定义了一个视图函数userinfo,对表单类UserInfoForm进行了实例化操作。详细说明如下:
- 在第05行代码,通过if条件语句判断HTTP请求方法,如果为POST方法,则继续执行后面代码去接收用户提交的数据;如果为GET方法,则直接跳转到第18行代码,执行第19行代码返回空的表单实例(from),让用户去录入数据再进行提交。
- 在第07行代码中,先通过request获取表单数据,再通过UserInfoForm表单类创建表单实例form。
- 在第09行代码中,通过if条件语句对表单实例form进行验证,如果所有的表单字段均有效,则继续执行下面的代码。
- 在第11~14行代码中,通过request获取表单字段数据,并保存在上下文变量context中。
- 在第16行代码中,将上下文变量context保存为字典类型变量userinfo,通过render()方法传递表单数据userinfo到新的页面中进行显示。
- 在第21行代码中,将表单实例form渲染到表单模板userinfo.html中。
6.2.3 模板处理
在Django框架表单中,模板的处理就相对简单得多。表单类UserInfoForm的模板代码如下:
【代码6-4】(详见源代码FormSite项目的formapp/templates/userinfo.html文件)
01 <form action="#" method="post">
02 {% csrf_token %}
03 {% for f in form %}
04 {{ f.label }}: {{ f }}<br><br>
05 {% endfor %}
06 <input type="submit" value="Submit" /><br>
07 </form>
【代码分析】
在第01~07行代码中,通过<form>标签定义了一个表单模板。
在第02行代码中,通过{% csrf_token %}模板标签为表单增加防护功能。Django框架自带一个简单易用的“跨站请求伪造防护”,当通过POST方法提交一个启用了CSRF防护(参见setting.py模块)的表单时,必须在表单中使用模板标签csrf_token。
在第03~05行代码中,通过{% for-endfor %}模板标签遍历表单实例form的每一项,并在页面模板中显示。
在第06行代码中,定义了表单的提交按钮<input type="submit" />。
现在,【代码6-4】为我们定义了一个可以工作的Web表单,其通过Django框架的Form类来描述,并由一个视图来处理并渲染成一个HTML模板中的表单(<form>)元素。
再介绍一下关于HTML 5输入类型和浏览器验证的内容。如果表单中包含类似URLField、EmailField或其他整数字段的类型,则Django模板表单将使用url、email和number这类的HTML 5输入类型。
在默认情况下,浏览器可能会在这些字段上应用自己的验证方式,这些验证方式可能会比Django框架的验证更加严格。如果想禁用这个行为,可以在<form>标签上设置novalidate属性,或者在字段上指定一个不同的控件(例如TextInput)。
6.2.4 提交模板
在前面的视图处理中,定义了一个用于显示表单提交数据的HTML模板,具体代码如下:
【代码6-5】(详见源代码FormSite项目的formapp/templates/show_info.html文件)
01 <!DOCTYPE html>
02 <html lang="en">
03 <head>
04 <meta charset="UTF-8">
05 <link rel="stylesheet" type="text/css" href="/static/css/myclass.css"/>
06 <title>Show Userinfo</title>
07 </head>
08 <body>
09 <p>
10 userinfo (total):<br>
11 {{ userinfo }}<br>
12 </p>
13 <p>
14 userinfo (items):<br>
15 {% for key,value in userinfo.items %}
16 {{ key }} : {{ value }}<br>
17 {% endfor %}
18 </p>
19 </body>
20 </html>
【代码分析】
在第11行代码中,直接通过字典类型的上下文变量userinfo在页面模板中输出表单提交的数据信息。
在第15~17行代码中,通过{% for-endfor %}模板标签遍历字典类型的上下文变量userinfo中的每一项,并依次在页面模板中进行显示。
6.2.5 测试表单应用
现在,我们测试一下前面基于Django框架Form类构建的“用户信息”Web应用。
首先,通过FireFox浏览器打开一下FormSite项目中定义的formapp表单应用地址,具体如图6.1中的箭头和标识所示,HTML模板(userinfo.html)中显示了从表单模块(forms.py)和视图模块(views.py)中传递过来的空白的“用户信息”表单。
图6.1 测试formapp表单应用(1)
然后,在空白表单中录入用户信息,具体如图6.2中的箭头和标识所示,录入相关用户信息后,直接单击Submit按钮进行提交。表单提交后的页面效果如图6.3中的箭头和标识所示,页面中分别显示了两种格式的字典对象的内容,与图6.2中录入的用户信息是一致的。