Django博客教程(五):处理 http 请求完全解读

简介:

Web 应用的交互过程其实就是 http 请求与响应的过程。无论是在 PC 端还是移动端,我们通常使用浏览器来上网,我们的上网流程大致来说是这样的:

  1. 我们打开浏览器,在地址栏输入我们想访问的网址,比如 www.djangoproject.com(当然你也可能从收藏夹里直接打开网站,但本质上都是一样的。)
  2. 浏览器知道我们想要访问那个网址后,它在后台帮我们做了很多事情,主要就是把我们的访问意图包装成一个 http 请求,发给我们想要访问的网址所对应的服务器。通俗点说就是浏览器帮我们通知网站的服务器,说有人来访问你啦,访问的请求都写在 http 里了,你按照要求处理后告诉我,我再帮你回应他!
  3. 网站服务器处理了 http 请求,然后生成一段 http 响应给浏览器,浏览器解读这个响应,把相关的内容在浏览器里显示出来,于是我们就看到了网站的内容。比如你访问了社区主页 www.pythonzh.cn,服务器接收到这个请求后他就知道用户访问的是首页,首页显示的是全部帖子列表,于是它从数据库里把帖子数据取出来,生成一个写着这些数据的 html 文档,包装到 http 响应里发给浏览器,浏览器解读这个响应,把 html 文档显示出来,我们就看到了帖子列表的内容。

因此,django 作为一个 web 框架,它的使命就是处理流程中的第二步,接收浏览器发来的 http 请求,返回相应的 http 响应。于是引出这么几个问题:

  1. django 如何接收 http 请求?
  2. django 如何处理这个 http 请求?
  3. django 如何生成 http 响应?

对于如何处理这些问题,django 有其自身的一套规定的机制。我们按照 django 的规定,就能开发出我们所需的功能。我们先以一个最简单的 hello world 为例来看看 django 处理上述问题的机制是怎么样的。

首先 django 需要知道当用户访问不同的网址时,应该如何处理不同的网址。django 的做法是把不同的网址对应的处理函数写在一个 urls.py 文件里,当用户访问某个网址时,django 就去会这个文件里找,如果找到这个网址,就会调用和它绑定在一起的处理函数(叫做视图函数),下面是具体的做法,首先在 blog 应用的目录下创建一个 urls.py 文件,这时你的目录看起来是这样:


在 urls.py 中写入这些代码:


我们首先从 django.conf.urls 导入了 url 函数,又从当前目录下导入了 views 模块。然后我们把网址和处理函数的关系写在了 urlpatterns 列表里。绑定关系的写法是把网址和对应的处理函数作为参数传给 url 函数(第一个参数是网址,第二个参数是处理函数),另外我们还传递了另外一个参数 name,这个参数的值将作为处理函数 index 的别名,这在以后会用到。

注意这里我们的网址是用正则表达式写的,django 会用这个正则表达式去匹配用户实际输入的网址,如果匹配成功,就会调用其后面的视图函数做相应的处理。比如说我们本地开发服务器的域名是 127.0.0.1:8000,那么当用户输入网址:127.0.0.1:8000 后,django 首先会把域名(即 127.0.0.1)和端口号(8000)去掉,此时只剩下一个空字符串,而 r'^$' 的模式正是匹配一个空字符串(这个正则表达式的意思是以空字符串开头且以空字符串结尾),于是二者匹配,django 便会调用其对应的 views.index 函数。

第二步就是要实际编写我们的 views.index 视图函数了,按照惯例视图函数定义在 views.py 文件里:


我们前面说过,Web 服务器的作用就是接收来自用户的 http 请求,根据请求内容作出相应的处理,并把处理结果包装成 http 响应返回给用户。这个两行的函数体现了这个过程。它首先接受了一个名为 request 的参数,这个 request 就是 django 为我们封装好的 http 请求,它是类 HttpResponse 的一个实例。然后我们便直接返回了一个 http 响应给用户,这个 http 响应也是 django 帮我们封装好的,它是类 HttpResponse 的一个实例,只是我们给它传了一个自定义的字符串,用户接受到这个响应后就会在浏览器显示出我们传递的内容:“欢迎访问我的博客首页!”

还差最后一步了,我们前面建立了一个 urls.py 文件,并且绑定了 URL 和视图函数 index,但是 django 并不知道。django 匹配 url 是在 blogproject 的 urls.py 下的,所以我们要把我们自己写的 urls.py 文件包含到这个文件里去,打开这个文件看到如下内容:


修改成如下的形式:


这里 - 表示删掉这一行,+ 表示添加这一行。我们这里导入了一个 include 函数,然后利用这个函数把 blog 应用下的 urls.py 包含了进来。此外 include 前还有一个 r'',这是一个空字符串,这里也可以写其他字符串,django 会把这个字符串和后面 include 的 urls.py 文件中的 url 拼接。假如我们这里把 r'' 改成 r'blog/',而我们在 blog.urls 中写的url 是 r'^$',一个空字符串,那么 django 最终匹配的就是 blog/ 加上一个空字符串,即 blog/。

运行 python manage.py runserver 打开开发服务器,在浏览器输入开发服务器的地址http://127.0.0.1:8000/,可以看到我们返回的内容了:欢迎访问我的博客首页!

这基本上就上 django 的开发流程了,写好处理 http 请求和返回 http 响应的视图函数,然后把视图函数绑定到相应的 URL 上。但是等一等!我们看到在我们的视图函数里返回的是一个 HTTPResponse 类的实例,我们给他传入了一个我们希望显示在用户浏览器上的字符串。但是我们的博客不可能只显示这么一句话,它有可能会显示很长很长的内容,比如我们发布的博客文章列表,或者一大段的博客文章,我们不能每次都把这些大段大段的内容传给 HTTPResponse。于是 django 对这个问题给我们提供了一个好的方法,叫做模板系统。django 要我们把大段的文本写到一个文件里,然后 django 自己会去读取这个文件,django 再把读取到的内容传给 HTTPResponse。我们用模板系统来改造一下上面的例子。首先在我们的项目根目录下建立一个名为 templates 的文件夹,用来存放我们的模板。然后再建立一个名为 blog 的文件夹,用来存放和 blog 应用相关的模板。当然模板存放在哪里是无关紧要的,只要 django 能够找到的就好。但是我们建立这样的文件夹结构的目的是把不同应用用到的模板隔离开来,这样方便以后维护,养成良好的习惯。然后我们在 blog 目录下建立一个名为 index.html 的文件,写上下面的代码:


这是一个标准的 html 文档了,只是里面有两个比较奇怪的地方:{{ title }},{{ welcome }},这是 django 规定的语法。用 {{ }} 包起来的叫做模板变量。django 在读取这个模板的时候回根据我们传来值替换这些变量。最终在模板中显示的将会是我们传递的值。

模板写好了,还得告诉 django 去哪里找模板,在 settings.py 文件里设置一下模板文件所在的路径。在 settings.py 找到 TEMPLATES 选项,它的内容是这样的:


其中 DIRS 就是设置模板的路径,在 [] 中写入 os.path.join(BASE_DIR, 'templates'),变成这样:


这里 BASE_DIR 是 settings.py 前面定义的变量,记录的是工程根目录 blogproject 的值,在这个目录下有我们的模板目录 templates,于是利用os.path.join 把这两个路径连起来,构成完整的模板路径,django 就知道去这个路径下面找我们的模板了。

视图函数可以改一下了:


这里我们在是直接把字符串传给 HttpResponse 了,而是调用 django 提供了 render 函数,这个函数根据我们传入的参数来构造 HttpResponse。我们首先把 http 请求传了进去,然后它根据第二个参数的值 blog/index.html 找到我们的模板,然后读取模板中的内容,并且根据我们传入的 context 把模板中的变量替换为我们传递的值,{{ title }} 被替换成了 context 字典中 title 对应的值,同理 {{ welcome }} 也被替换成相应的值。最终,我们的 html 模板中的内容字符串被传递给 HttpResponse 对象并返回给浏览器,这样用户的浏览器上便显示出了我们写的 html 模板的内容。


原文发布时间为:2017-05-07

本文作者:追梦人物

本文来自云栖社区合作伙伴“Python中文社区”,了解相关信息可以关注“Python中文社区”微信公众号

相关文章
|
7天前
|
API 数据安全/隐私保护
Haskell中的HTTP请求:代理与响应状态检查
Haskell中的HTTP请求:代理与响应状态检查
|
1月前
|
缓存 应用服务中间件 Apache
HTTP 范围Range请求
HTTP范围请求是一种强大的技术,允许客户端请求资源的部分内容,提高了传输效率和用户体验。通过正确配置服务器和实现范围请求,可以在视频流、断点续传下载等场景中发挥重要作用。希望本文提供的详细介绍和示例代码能帮助您更好地理解和应用这一技术。
92 19
|
2月前
|
JSON 数据格式
.net HTTP请求类封装
`HttpRequestHelper` 是一个用于简化 HTTP 请求的辅助类,支持发送 GET 和 POST 请求。它使用 `HttpClient` 发起请求,并通过 `Newtonsoft.Json` 处理 JSON 数据。示例展示了如何使用该类发送请求并处理响应。注意事项包括:简单的错误处理、需安装 `Newtonsoft.Json` 依赖,以及建议重用 `HttpClient` 实例以优化性能。
89 2
|
2月前
|
JSON JavaScript 前端开发
什么是HTTP POST请求?初学者指南与示范
HTTP POST请求是一种常用的HTTP方法,主要用于向服务器发送数据。通过合理设置请求头和请求主体,可以实现数据的可靠传输。无论是在客户端使用JavaScript,还是在服务器端使用Node.js,理解和掌握POST请求的工作原理和应用场景,对于Web开发至关重要。
369 18
|
2月前
|
网络协议 应用服务中间件 网络安全
免费泛域名https证书教程—无限免费续签
随着互联网安全意识提升,越来越多网站采用HTTPS协议。本文介绍如何通过JoySSL轻松获取并实现免费泛域名SSL证书的无限续签。JoySSL提供永久免费通配符SSL证书,支持无限制域名申请及自动续签,全中文界面适合国内用户。教程涵盖注册账号、选择证书类型、验证域名所有权、下载与安装证书以及设置自动续签等步骤,帮助网站简化SSL证书管理流程,确保长期安全性。
|
2月前
|
Web App开发 大数据 应用服务中间件
什么是 HTTP Range请求(范围请求)
HTTP Range 请求是一种非常有用的 HTTP 功能,允许客户端请求资源的特定部分,从而提高传输效率和用户体验。通过合理使用 Range 请求,可以实现断点续传、视频流播放和按需加载等功能。了解并掌握 HTTP Range 请求的工作原理和应用场景,对开发高效的网络应用至关重要。
223 15
|
2月前
|
Web App开发 网络安全 数据安全/隐私保护
Lua中实现HTTP请求的User-Agent自定义
Lua中实现HTTP请求的User-Agent自定义
|
2月前
|
JSON Java 数据格式
java操作http请求针对不同提交方式(application/json和application/x-www-form-urlencoded)
java操作http请求针对不同提交方式(application/json和application/x-www-form-urlencoded)
107 25
java操作http请求针对不同提交方式(application/json和application/x-www-form-urlencoded)
|
2月前
|
安全 数据安全/隐私保护
IP地址https证书免费申请教程
本教程详细介绍如何免费申请IP地址HTTPS证书,涵盖准备、申请、审核、下载与部署阶段。从确认IP地址、选择CA、注册账户到验证控制权,最后完成证书部署,确保数据传输安全。注意证书有效期较短,需及时续签。
|
2月前
|
数据采集 JSON 测试技术
Grequests,非常 Nice 的 Python 异步 HTTP 请求神器
在Python开发中,处理HTTP请求至关重要。`grequests`库基于`requests`,支持异步请求,通过`gevent`实现并发,提高性能。本文介绍了`grequests`的安装、基本与高级功能,如GET/POST请求、并发控制等,并探讨其在实际项目中的应用。
79 3