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


HTTP 请求

HTTP协议以"请求-回复"的方式工作。客户发送请求时,可以在请求中附加数据。服务器通过解析请求,就可以获得客户传来的数据,并根据URL来提供特定的服务。

GET 方法

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

/HelloWorld/HelloWorld/search.py 文件代码:

# -*- coding: utf-8 -*-from django.http import HttpResponse
from django.shortcuts import render# 表单
def search_form(request):return render(request,'search_form.html')# 接收请求数据
def search(request):request.encoding = 'utf-8'if 'q' in request.GET and request.GET['q']:message = '你搜索的内容为: ' + request.GET['q']else:message = '你提交了空表单'return HttpResponse(message)

在模板目录 templates 中添加 search_form.html 表单:

/HelloWorld/templates/search_form.html 文件代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</title>
</head>
<body><form action="/search" method="get"><input type="text" name="q"><input type="submit" value="搜索"></form>
</body>
</html>

urls.py 规则修改为如下形式:

/HelloWorld/HelloWorld/urls.py 文件代码:

from django.conf.urls import url
from . import view,testdb,searchurlpatterns = [url(r'^hello$', view.hello),url(r'^testdb$', testdb.testdb),url(r'^search-form$', search.search_form),url(r'^search$', search.search),
]

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

POST 方法

上面我们使用了GET方法。视图显示和请求处理分成两个函数处理。

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

我们在 templates 创建 post.html:

/HelloWorld/templates/post.html 文件代码:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>菜鸟教程(runoob.com)</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 全称是 Cross Site Request Forgery。这是Django提供的防止伪装提交请求的功能。POST 方法提交的表格,必须有此标签。

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

/HelloWorld/HelloWorld/search2.py 文件代码:

# -*- coding: utf-8 -*-from django.shortcuts import render
from django.views.decorators import csrf# 接收POST请求数据
def search_post(request):ctx ={}if request.POST:ctx['rlt'] = request.POST['q']return render(request, "post.html", ctx)

urls.py 规则修改为如下形式:

/HelloWorld/HelloWorld/urls.py 文件代码:

from django.conf.urls import url
from . import view,testdb,search,search2urlpatterns = [url(r'^hello$', view.hello),url(r'^testdb$', testdb.testdb),url(r'^search-form$', search.search_form),url(r'^search$', search.search),url(r'^search-post$', search2.search_post),
]

访问 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
|   |-- view.py
|   |-- view.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 对象

每个 view 函数的第一个参数是一个 HttpRequest 对象,就像下面这个 hello() 函数:

from django.http import HttpResponsedef hello(request):return HttpResponse("Hello world")

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

属性

描述

path

请求页面的全路径,不包括域名—例如, "/hello/"。

method

请求中使用的HTTP方法的字符串表示。全大写表示。例如:

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

GET

包含所有HTTP GET参数的类字典对象。参见QueryDict 文档。

POST

包含所有HTTP POST参数的类字典对象。参见QueryDict 文档。

服务器收到空的POST请求的情况也是有可能发生的。也就是说,表单form通过HTTP POST方法提交请求,但是表单中可以没有数据。因此,不能使用语句if request.POST来判断是否使用HTTP POST方法;应该使用if request.method == "POST" (参见本表的method属性)。

注意: POST不包括file-upload信息。参见FILES属性。

REQUEST

为了方便,该属性是POST和GET属性的集合体,但是有特殊性,先查找POST属性,然后再查找GET属性。借鉴PHP's $_REQUEST。

例如,如果GET = {"name": "john"} 和POST = {"age": '34'},则 REQUEST["name"] 的值是"john", REQUEST["age"]的值是"34".

强烈建议使用GET and POST,因为这两个属性更加显式化,写出的代码也更易理解。

COOKIES

包含所有cookies的标准Python字典对象。Keys和values都是字符串。

FILES

包含所有上传文件的类字典对象。FILES中的每个Key都是<input type="file" name="" />标签中name属性的值. FILES中的每个value 同时也是一个标准Python字典对象,包含下面三个Keys:

  • filename: 上传文件名,用Python字符串表示
  • content-type: 上传文件的Content type
  • content: 上传文件的原始内容

注意:只有在请求方法是POST,并且请求页面中<form>有enctype="multipart/form-data"属性时FILES才拥有数据。否则,FILES 是一个空字典。

META

包含所有可用HTTP头部信息的字典。 例如:

  • CONTENT_LENGTH
  • CONTENT_TYPE
  • QUERY_STRING: 未解析的原始查询字符串
  • REMOTE_ADDR: 客户端IP地址
  • REMOTE_HOST: 客户端主机名
  • SERVER_NAME: 服务器主机名
  • SERVER_PORT: 服务器端口

META 中这些头加上前缀 HTTP_ 为 Key, 冒号(:)后面的为 Value, 例如:

  • HTTP_ACCEPT_ENCODING
  • HTTP_ACCEPT_LANGUAGE
  • HTTP_HOST: 客户发送的HTTP主机头信息
  • HTTP_REFERER: referring页
  • HTTP_USER_AGENT: 客户端的user-agent字符串
  • HTTP_X_BENDER: X-Bender头信息

user

是一个django.contrib.auth.models.User 对象,代表当前登录的用户。

如果访问用户当前没有登录,user将被初始化为django.contrib.auth.models.AnonymousUser的实例。

你可以通过user的is_authenticated()方法来辨别用户是否登录:

if request.user.is_authenticated():# Do something for logged-in users.
else:# Do something for anonymous users.

只有激活Django中的AuthenticationMiddleware时该属性才可用

session

唯一可读写的属性,代表当前会话的字典对象。只有激活Django中的session支持时该属性才可用。

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 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实现所有标准的词典方法。还包括一些特有的方法:

方法 描述

__getitem__

和标准字典的处理有一点不同,就是,如果Key对应多个Value,__getitem__()返回最后一个value。

__setitem__

设置参数指定key的value列表(一个Python list)。注意:它只能在一个mutable QueryDict 对象上被调用(就是通过copy()产生的一个QueryDict对象的拷贝).

get()

如果key对应多个value,get()返回最后一个value。

update()

参数可以是QueryDict,也可以是标准字典。和标准字典的update方法不同,该方法添加字典 items,而不是替换它们:

>>> 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__():

>>> q = QueryDict('a=1&a=2&a=3')>>> q.items()[('a', '3')]

values()

和标准字典的values()方法有一点不同,该方法使用单值逻辑的__getitem__():

此外, QueryDict也有一些方法,如下表:

方法 描述

copy()

返回对象的拷贝,内部实现是用Python标准库的copy.deepcopy()。该拷贝是mutable(可更改的) — 就是说,可以更改该拷贝的值。

getlist(key)

返回和参数key对应的所有值,作为一个Python list返回。如果key不存在,则返回空list。 It's guaranteed to return a list of some sort..

setlist(key,list_)

设置key的值为list_ (unlike __setitem__()).

appendlist(key,item)

添加item到和key关联的内部list.

setlistdefault(key,list)

和setdefault有一点不同,它接受list而不是单个value作为参数。

lists()

和items()有一点不同, 它会返回key的所有值,作为一个list, 例如:

>>> q = QueryDict('a=1&a=2&a=3')>>> q.lists()[('a', ['1', '2', '3'])]

urlencode()

返回一个以查询字符串格式进行格式化后的字符串(例如:"a=2&b=3&b=5")。

更多内容,可关注作者的微信公众号:胖哥真不错。

Python Django框架学习07:Django表单相关推荐

  1. python表单提交的两种方式_Flask框架学习笔记之表单基础介绍与表单提交方式

    本文实例讲述了Flask框架学习笔记之表单基础介绍与表单提交方式.分享给大家供大家参考,具体如下: 表单介绍 表单是HTML页面中负责数据采集功能的部件.由表单标签,表单域和表单按钮组成.通过表单,将 ...

  2. python web报表_python django框架 渲染和ajax表单提交周报表

    一. 实际需求 之前这篇文章kettle-自动生成周报 是使用java开源ETL工具kettle实现,正常情况下是每天写工作完成情况到Excel表,每周五定时任务启动读取Excel日志写入数据库,再读 ...

  3. Django框架下的form表单提交数据(及文件)获取的方法

    目录 一.文件的提交和获取 1.html代码: 2.django代码: 二.文本的提交和获取 html: urls.py: ​编辑 views.py: ​编辑 结果: 一.文件的提交和获取 一般思路为 ...

  4. Django框架学习

    Django是现在世界上python语言应用最广泛.发展最成熟的web框架.它足够完整 ,不需要依赖其他就可以开发出 非常完整的web应用.Django的主要内容如下: Django综述:了解Djan ...

  5. Django框架学习(一)Django框架安装和项目创建详解

    Django框架学习(一)Django框架安装和项目创建详解 文章目录 Django框架学习(一)Django框架安装和项目创建详解 一.简介 1.1介绍 1.2 URL 1.3.框架原理 二.安装 ...

  6. python 显示html_如何使用python在本地显示带有html表单的网...

    我是一名行为科学家,通常通过让参与者在计算机上执行某些任务并记录他们的响应来收集数据(我使用pyglet包装器PsychoPy编写程序).也就是说,程序在本地运行,数据存储在本地. 现在我想知道是否有 ...

  7. ASP.NET MVC 2 学习笔记二: 表单的灵活提交

    ASP.NET MVC 2 学习笔记二:  表单的灵活提交 前面说到有做到公司内部的一个请假系统,用的是ASP.NET MVC 2+Entity Framework.虽然EF(Entity Frame ...

  8. Layui框架form模块的表单验证

    在layui框架里边针对于表单元素做了比较多的功能,下面将介绍的功能就是form模块里面自00带的表单验证功能,该功能可以在提交表单时自动验证表单. 首先要使用form模块时需要加载模块,这是所有模块 ...

  9. Python Web开发——Django框架学习

    文章目录 Web开发简介 Web应用技术 Web前端开发 Web后端开发 使用 Django 开发后端服务 项目目标 管理员操作 登录界面 客户管理界面 添加客户界面 药品管理界面 添加药品界面 订单 ...

最新文章

  1. 使用struts2框架来实现CRUD(create、read、update、delete)
  2. Github上的10个数据科学和机器学习知识库
  3. amazeui学习笔记--css(基本样式)--样式统一Normalize
  4. 36、Power Query-多条件合并查询
  5. 参数整定临界比例度实验_实验低温浴“秘方”,调节两个溶剂的比例实现零下10度到78度定温配制...
  6. c fread 快读 详解_奔驰ACC(自适应巡航系统)详解
  7. 玩,玩什么,怎么玩?
  8. 苹果一半员工未接受4年制大学教育 库克却对此感到骄傲
  9. hive动态分区shell_Hive/Shell 创建Hive 库 ,表脚本,Hive 动态增加分区脚本
  10. win7从光盘进入修复计算机,怎么用光盘修复win7_win7如何用光盘修复系统
  11. 【Python】自动抠图换背景
  12. Anker-一个研发工程师的电商梦
  13. Spark复习大纲,有需要的小伙伴可以点个赞找我私信
  14. 如何选择回归损失函数
  15. 草莓 西瓜 柚子……
  16. HTML图片上传服务器
  17. 李开复:如何做最好的创新
  18. python爬取推特的详细教程_使用Selenium Python进行网页抓取[Twitter+Instagram]
  19. [转]Flex 处理bmp图片as
  20. 2004年电子政务IT100强榜单

热门文章

  1. 解决报错:WebSocket connection to ‘ws://124.207.120.104:9502/‘ failed: Error in connection establish
  2. Hibernate中hibernate.cfg.xml核心配置文件配置
  3. Word文档被限制编辑,怎么破?
  4. 牧羊人惠普所有天气和货物向量
  5. 【Google Play】管理目标受众群体 ( 加入“亲子同乐计划“ | 应用受众覆盖所有年龄段 )
  6. 频率可调SPWM三相输出:
  7. Python数据分析速成课程
  8. 基于BGL的社团结构检测
  9. WIN10-微软输入法添加日语或者其他语言
  10. “种一棵树最好的时间是十年前,其次是现在。”