表单的使用
关于此文档
此文档提供基本的web表单介绍和Django中如何处理表单。关于更多的具体细节,可以查阅更多详细文档。
除非你计划构建的网站和应用不发布任何内容,不接受用户输入的数据,否则你需要理解和使用表单。
Django提供一些工具和库帮助你创建表单接收用户的输入,并处理和返回数据。
HTML 表单
在HTML中,表单在<form>..</form>
里面收集用户的输入,例如一段文本,选择按钮等,然后发送输入的信息到服务端。
一些表单接口元素,例如文本输入、复选框都非常的简单并且是HTML内置的,其他的要复杂很多比如界面弹出日期选择器、滑动滑块,操纵这些特效通常会使用JavaScript和 CSS来实现。
关于<input>
元素,一个表单必须指定两件事:
- where:用户输入数据所对应的URL如何返回
- how:HTTP方法如何返回数据
一个例子,Django的Admin中有一个登陆表单,包含几个<input>
元素,type="text"
对应username
,type="password"
对应password
,type="submit"
对应登录按钮,还包含一些对用户隐藏的文本字段,令Django决定接下来要干什么。
GET和POST
GET和POST是处理表单过程中唯一使用的HTML方法
Django的login表单使用POST方法,在浏览器中打包表单数据,编码传输,将其发送给服务器,然后接收返回的响应。
对比GET,绑定提交的数据到字符串生成URL,在URL中包含数据必须发送的地址以及数据的键和值,如果你在文档中搜索可以在功能中看见,将会为表单生成这样的URL:
https://docs.djangoproject.com/search/?q=forms&release=1.
GET和POST通常用于不同目的
一个请求如果用来改变系统的状态,例如:一个请求改变了数据库,应该使用POST,GET应该在不会改变系统状态的情况下使用。
GET不适合用于密码表单,因为密码会出现在URL里,因此,在浏览器的历史记录和服务器日志的纯文本中会出现密码。它也不能适用于大量的数据,类似图片的二进制数据。一个web应用使用GET请求管理员表单会带来安全风险,攻击者会很容易的模仿表单请求获取系统敏感信息,POST结合其他的保护措施,提供更多的访问控制,例如:CSRF protection
在其他方面,GET适合web搜索表单,因为这个URL的GET请求可以方便的存为书签、共享、提交。
Djano表单的作用
处理表单是一项复杂的业务,考虑Django管理员,众多的数据和几个不同的数据类型需要显示在表单里,渲染到HTML,使用方便的界面编辑,返回到服务器,验证和清理,保存或进一步的加工处理。
Django表单函数可以使绝大部分的工作简单化、自动化,并且比大多数程序员自己写的代码要安全。
Django处理3个不同的表单部分:
- 预备和调整数据渲染页面
- 创建HTML表单数据格式
- 接收处理客户端提交的表单和数据
你可能想手动的完成这些功能,但是Django可以帮你完成这些。
Django表单
我们简要的描述HTML表单,但是HTML<form>
只是一部分机械的要求。
在web应用程序的上下文,form可能是指HTML<form>
,或Djangoform
类实例,或结构化数据提交时返回,或这些部位的端到端的集合。
Django表单类
这个系统组件的核心是Djangoform
类,在Django模型中描述了相似的逻辑结构对象,它的行为,form
类描述表单如何工作和创建。
使用与model
类相似的字段映射数据库方式,form
类字段映射HTML表单<input>
元素。
表单的字段是类本身,它们管理表单数据, 提交的时候执行验证。DateField和FileField处理不同的数据,用它们做不同的事情。
一个表单字段代表一个用户在浏览器中的widget(窗口部件)--用户界面的机制,每个字段类型有一个默认的Widget class,但是它们可以按要求重写。
实例化,处理,渲染表单
在Django渲染一个对象,我们一般:
1.在视图(view)中抓住它(从数据库中取出)
2.传送它到模版文件
3.扩大到使用模版变量的HTML标签
在模版中渲染一个表单与渲染其他对象很相似,但是有些键值不一样。
模型实例中不包含数据,且几乎很少在模版中做任何有用的事情,另一方面,它塑造一种完美的感觉渲染一个未填充的表单,我们想要用户填充它,这就是我们想要的。
当我们在view中处理一个模型实例,我们通常在数据库中检索,当我们处理一个表单我们通常在view中实例化它。
当我们实例化一个表单,我们可以选择让它空着或者预填充,例如:
- 数据表单保存在模型(model)实例
- 我们从其他来源收集的数据
- 以前的HTML表单提交接收的数据
剩下的这些案例都是非常有趣的,它让用户不只是阅读网页,发送信息与网站交互。
建立一个表单
需要完成的工作
假设在你的网站上创建一个简单的表单,获取用户的名字,你需要在模版(tempalte)中添加以下代码:
<form action="/your-name/" method="post">
<label for="your_name">Your name: </label>
<input id="your_name" type="text" name="your_name" value="{{ current_name }}">
<input type="submit" value="OK">
</form>
这些告诉浏览器返回表单数据到URL/your-name/,使用POST方法,它会显示一个文本框,标记为“your_name”,和一个按钮标记为“ok”,如果模版上下文包含一个current_name变量,将会预填充your_name字段。
你需要在view中渲染包含HTML表单的模版,并且可以适当的绑定current_name字段
当表单提交之后,POST请求发送到服务器将包含表单数据。
现在你需要在view中处理相应的 /your-name/ URL映射,将会在请求发现相应的键/值对应,然后处理他们。
这是一个非常简单的表单,在实践中,一个表单可能包含几十个甚至几百个字段,这些可能需要预填充,我们可能期待用户在最后提交之前,分成几个周期编辑提交数据。
我们可能需要一些验证在浏览器中出现,即使在表单提交。我们可能想要使用一些复杂的字段,允许用户从日历选择日期等。