HTML表单是网站交互性的经典方式。 本章将介绍如何用Django对用户提交的表单数据进行处理。
HTTP 请求
HTTP协议以"请求-回复"的方式工作。客户发送请求时,可以在请求中附加数据。服务器通过解析请求,就可以获得客户传来的数据,并根据URL来提供特定的服务。
GET 方法
我们在之前的项目中创建一个 search.py 文件,用于接收用户的请求:
在模板目录 templates 中添加 search_form.html 表单:
urls.py 规则修改为如下形式:
访问地址 http://127.0.0.1:8000/search-form/ 并搜索,结果如下所示:
POST 方法
上面我们使用了 GET 方法,视图显示和请求处理分成两个函数处理。
提交数据时更常用 POST 方法。我们下面使用该方法,并用一个URL和处理函数,同时显示视图和处理请求。
我们在 templates 创建 post.html:
在模板的末尾,我们增加一个 rlt 记号,为表格处理结果预留位置。
表格后面还有一个 {% csrf_token %} 的标签。csrf 全称是 Cross Site Request Forgery。这是 Django 提供的防止伪装提交请求的功能。POST 方法提交的表格,必须有此标签。
在HelloWorld目录下新建 search2.py 文件并使用 search_post 函数来处理 POST 请求:
urls.py 规则修改为如下形式:
访问 http://127.0.0.1:8000/search-post/ 显示结果如下:
完成以上实例后,我们的目录结构为:
HelloWorld |-- HelloWorld | |-- __init__.py | |-- __init__.pyc | |-- search.py | |-- search.pyc | |-- search2.py | |-- search2.pyc | |-- settings.py | |-- settings.pyc | |-- testdb.py | |-- testdb.pyc | |-- urls.py | |-- urls.pyc | |-- views.py | |-- views.pyc | |-- wsgi.py | `-- wsgi.pyc |-- TestModel | |-- __init__.py | |-- __init__.pyc | |-- admin.py | |-- admin.pyc | |-- apps.py | |-- migrations | | |-- 0001_initial.py | | |-- 0001_initial.pyc | | |-- __init__.py | | `-- __init__.pyc | |-- models.py | |-- models.pyc | |-- tests.py | `-- views.py |-- db.sqlite3 |-- manage.py `-- templates |-- base.html |-- hello.html |-- post.html `-- search_form.html
Request 对象
每个视图函数的第一个参数是一个 HttpRequest 对象,就像下面这个 runoob() 函数:
from django.http import HttpResponse def runoob(request): return HttpResponse("Hello world")
HttpRequest对象包含当前请求URL的一些信息:
if request.user.is_authenticated(): # Do something for logged-in users. else: # Do something for anonymous users.
Request对象也有一些有用的方法:
方法 | 描述 |
---|---|
__getitem__(key) |
返回GET/POST的键值,先取POST,后取GET。如果键不存在抛出 KeyError。
这是我们可以使用字典语法访问HttpRequest对象。 例如,request["foo"]等同于先request.POST["foo"] 然后 request.GET["foo"]的操作。 |
has_key() | 检查request.GET or request.POST中是否包含参数指定的Key。 |
get_full_path() | 返回包含查询字符串的请求路径。例如, "/music/bands/the_beatles/?print=true" |
is_secure() | 如果请求是安全的,返回True,就是说,发出的是HTTPS请求。 |
QueryDict对象
在HttpRequest对象中, GET和POST属性是django.http.QueryDict类的实例。
QueryDict类似字典的自定义类,用来处理单键对应多值的情况。
QueryDict实现所有标准的词典方法。还包括一些特有的方法:
>>> q = QueryDict('a=1') >>> q = q.copy() # to make it mutable >>> q.update({'a': '2'}) >>> q.getlist('a') ['1', '2'] >>> q['a'] # returns the last ['2']
>>> q = QueryDict('a=1&a=2&a=3') >>> q.items() [('a', '3')]
此外, QueryDict也有一些方法,如下表:
>>> q = QueryDict('a=1&a=2&a=3') >>> q.lists() [('a', ['1', '2', '3'])]