Code前端首页关于Code前端联系我们

Django 表单:处理用户提交的表单数据

terry 2年前 (2023-09-25) 阅读数 52 #后端开发

HTML 表单是网站交互的经典方式。本章介绍如何使用Django处理用户提交的表单数据。


HTTP 请求

HTTP 协议以“请求-响应”方式工作。当客户发送请求时,他们可以向请求添加数据。服务器通过解析请求,可以获得客户端发送的数据,并根据URL提供特定的服务。

GET方法

我们在上一个项目中创建了一个search.py​​文件,用于接收用户请求:

# -*- coding: utf-8 -*-

from django.http import HttpResponse
from django.shortcuts import render_to_response

# 表单
def search_form(request):
	return render_to_response('search_form.html')

# 接收请求数据
def search(request):  
	request.encoding='utf-8'
	if 'q' in request.GET:
		message = '你搜索的内容为: ' + request.GET['q'].encode('utf-8')
	else:
		message = '你提交了空表单'
	return HttpResponse(message)

将search_form.html表单添加到template文件夹template中:

<html>
<head>
	<meta charset="utf-8" /> 
    <title>Search - w3cschool.cc</title>
</head>
<body>
    <form action="/search/" method="get">
        <input type="text" name="q">
        <input type="submit" value="Search">
    </form>
</body>
</html>

u​​rls.py行更改它有如下形式:

from django.conf.urls import *
from HelloWorld.view import hello
from HelloWorld.testdb import testdb
from HelloWorld import search

urlpatterns = patterns("",
	('^hello/$', hello),
	('^testdb/$', testdb),
	(r'^search-form/$', search.search_form),
	(r'^search/$', search.search),
)

访问地址:http://192.168.45.3:8000/search-form/并搜索,结果如下:

Django 表单:对用户提交的表单数据进行处理

Django 表单:对用户提交的表单数据进行处理

POST方法

我们使用了上面的GET方法。显示渲染和请求处理分为两个功能。

提交数据时更常用POST方法。我们在下面使用这个方法,并使用 URL 和处理函数来显示视图并同时处理请求。

我们在tmplate中创建post.html:

<html>
<head>
	<meta charset="utf-8" /> 
    <title>Search - w3cschool.cc</title>
</head>
<body>
	<form action="/search-post/" method="post">
		{% csrf_token %}
		<input type="text" name="q">
		<input type="submit" value="Submit">
	</form>

	<p>{{ rlt }}</p>
</body>
</html>

在模板的末尾我们添加一个rlt标记来为表格处理结果保留一个位置。

表单后面还有一个标签{% csrf_token %}。 csrf的全称是跨站请求伪造。这是Django的一个功能,用于防止伪装的提交请求。通过 POST 方法发送的表单必须具有此标记。

在HelloWorld目录下新建search2.py文件,使用search_post函数处理POST请求:

# -*- coding: utf-8 -*-

from django.shortcuts import render
from django.core.context_processors import csrf

# 接收POST请求数据
def search_post(request):
	ctx ={}
	ctx.update(csrf(request))
	if request.POST:
		ctx['rlt'] = request.POST['q']
	return render(request, "post.html", ctx)

urls.py 规则更改如下:

from django.conf.urls import *
from HelloWorld.view import hello
from HelloWorld.testdb import testdb
from HelloWorld import search
from HelloWorld import search2

urlpatterns = patterns("",
	('^hello/$', hello),
	('^testdb/$', testdb),
	(r'^search-form/$', search.search_form),
	(r'^search/$', search.search),
	(r'^search-post/$', search2.search_post),
)

转到http://192.168.45.3 : 8000/search-post / 显示结果如下:

Django 表单:对用户提交的表单数据进行处理

完成上面的例子后,我们的目录结构是:

HelloWorld
|-- HelloWorld
|   |-- __init__.py
|   |-- __init__.pyc
|   |-- models.pyc
|   |-- search.py
|   |-- search.pyc
|   |-- search2.py
|   |-- search2.pyc
|   |-- settings.py
|   |-- settings.pyc
|   |-- testdb.py
|   |-- testdb.pyc
|   |-- urls.py
|   |-- urls.pyc
|   |-- view.py
|   |-- view.pyc
|   |-- wsgi.py
|   `-- wsgi.pyc
|-- TestModel
|   |-- __init__.py
|   |-- __init__.pyc
|   |-- admin.py
|   |-- models.py
|   |-- models.pyc
|   |-- tests.py
|   `-- views.py
|-- manage.py
`-- templates
    |-- base.html
    |-- hello.html
    |-- post.html
    `-- search_form.html

3 directories, 29 files

Request对象

每个显示函数的第一个参数是一个HttpRequest对象,就像以下 hello() 函数:

from django.http import HttpResponse

def hello(request):
    return HttpResponse("Hello world")

HttpRequest 对象包含有关当前请求的 URL 的一些信息:

属性 描述
路径请求页面的完整路径,不包括域名 -例如“/你好/”。
method 请求中使用的 HTTP 方法的字符串表示形式。用大写字母表示。例如:

if request.method == 'GET':
do_something()
elif request.method == 'POST':
do_something_else()

GET包含所有HTTP 类似字典的 GET 参数对象。请参阅 QueryDict 文档。
POST 一个类似字典的对象,包含所有 HTTP POST 参数。请参阅 QueryDict 文档。

服务器也有可能收到一个空的POST请求。换句话说,表单通过 HTTP POST 方法发送请求,但表单中没有数据。因此,不能使用if request.POST语句来判断是否使用HTTP POST方法;请改用 if request.method == "POST" (请参阅此表中的方法属性)。

注意:POST 不包含文件上传信息。请参阅 FILES 属性。

REQUEST为了方便起见,该属性是POST和GET属性的集合,但它有特殊的功能。首先查找 POST 属性,然后查找 GET 属性。学习PHP的$_REQUEST。

如果 GET = {"name": "john"} 且 POST = {"age": '34'},则 REQUEST["name"] 的值为 "john",REQUEST["age "] 的值为“34”。

强烈建议使用 GET 和 POST,因为这两个属性更明确,写出的代码也更容易理解。

COOKIES 包含所有 cookie 的标准 Python 字典对象。键和值都是字符串。有关 cookie 的更详细说明,请参阅第 12 章。
FILES 一个类似字典的对象,包含所有上传的文件。FILES 中的每个键都是 标记中 name 属性的值。 FILES 中的每个值也是一个标准的 Python 字典对象,包括以下三个键:
  • filename:上传文件的名称,以 Python 字符串表示
  • content-type:上传文件的内容类型
  • content:上传文件的原始内容

注意:只有当请求方式为POST且请求页面FILES包含数据时,只有具有enctype="multipart/form-data"属性。否则,FILES 是一个空字典。

META 包含所有可用 HTTP 标头信息的字典。例如:
  • CONTENT_LENGTH
  • CONTENT_TYPE
  • QUERY_STRING:未解析的原始查询字符串
  • REMOTE_ADDR:客户端 IP 地址
  • REMOTE_HOST:客户端主机名
  • SERVER_NAME:服务器主机名
  • SERVER_PORT:服务器端口

META 这些 header 以 HTTP_ 为前缀作为 key,例如:

  • HTTP_ACCEPT_ENCODING
  • HTTP_ACCEPT_LANGUAGE
  • HTTP_HOST:客户端发送的 HTTP 主机头信息 HTTP_RE FERER :引用第
  • HTTP_USER_AGENT :客户端用户代理字符串
  • HTTP_X_BENDER:

    如果访问用户当前未登录,则该用户将被初始化为 django.contrib.auth.models.AnonymousUser 的实例。 ?字典对象。仅当 Django 中启用了会话支持时,此属性才可用。请参阅第 12 章。

raw_post_data原始 HTTP POST 数据,未解析。对于高级加工很有用。

Request 对象还有一些有用的方法:

方法 描述
__getitem__(key)返回 GET/POST 的键值,先取 POST,再取 GET。如果密钥不存在,则抛出 KeyError。
这是我们使用字典语法访问 HttpRequest 对象的地方。例如,
Request["foo"] 等于 request.POST["foo"] 然后是 request.GET["foo"]。
has_key() 检查 request.GET 或 request.POST 是否包含参数指定的 key。
get_full_path() 返回包含查询字符串的请求路径。例如:“/music/bands/the_beatles/?print=true”
is_secure() 如果请求是安全的,即发送了 HTTPS 请求,则返回 True。

QueryDict 对象

在 HttpRequest 对象中,GET 和 POST 属性是 django.http.QueryDict 类的实例。

QueryDict 是一个类似字典的自定义类,用于处理单个键匹配多​​个值的情况。

QueryDict 实现了所有标准字典方法。它还包含一些独特的方法:

方法 描述
__getitem__ 与标准字典处理略有不同,即如果 Key 匹配多个值,__getitem__() 返回最后一个值。
__setitem__ 设置参数指定的键的值列表(Python 列表)。注意:它只能在可变的 QueryDict 对象(即由 copy() 生成的 QueryDict 对象的副本)上调用。
get()如果键匹配多个值,get() 返回最后一个值。
update()参数可以是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']
items() 它与标准字典的 items() 方法略有不同。该方法使用单值逻辑 __getitem__( ; 方法 描述
copy() 返回对象的副本。内部实现是来自 Python 标准库的 copy.deepcopy()。副本为mutable:即副本的值是可以改变的。
getlist(key)以Python列表的形式返回参数key对应的所有值,如果key不存在则有一个空list 保证返回某个列表。
setlist(key,list_)将 key 的值设置为 list_(而不是 __setitem__())。
appendlist(key,item)将项目添加到与键关联的内部列表。
setlistdefault(key, list) 与 setdefault 略有不同,因为它接受列表而不是单个值作为参数。
lists () 略有不同与 items() 不同,它以列表的形式返回键的所有值,例如:
>>> q = QueryDict('a=1&a=2&a=3')

>>> q.lists()

[('a', ['1', '2', '3'])]
urlencode() 返回格式为 The string after 的查询字符串(例如"a=2&b=3&b=5").

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门