00-django | 02-处理HTTP请求
00-django | 02-处理HTTP请求
Django 处理 HTTP 请求
Hello 视图函数
我们先以一个最简单的 Hello World 为例来看看 django 处理上述问题的机制是怎么样的。
绑定 URL 与视图函数
当用户访问不同的网址时,Django需要知道如何处理这些网址(路由)。django 的做法是把不同的网址对应的处理函数写在一个urls.py
文件里,当用户访问某个网址时,django 就去会这个文件里找,如果找到这个网址,就会调用和它绑定在一起的处理函数(叫做视图函数)。下面是具体的做法,首先在 blog 应用的目录下创建一个 urls.py 文件,这时你的目录看起来是这样:
.
├── __init__.py
├── admin.py
├── apps.py
├── migrations
├── models.py
├── static
├── tests.py
├── urls.py #这个
└── views.py
urls.py
在 blog\urls.py 中写入这些代码:
from django.urls import path
from . import views
urlpatterns = [
path('', views.index, name='index'),
]
解释:
- 从
django.urls
模块中导入了path
函数;并从当前目录导入了views
模块。也就是上面view.py
这个文件 - 将网址和处理函数的关系作为参数传给
path
函数(网址,处理函数,处理函数的别名) - 我们本地开发服务器的域名是 http://127.0.0.1:8000, 那么当用户输入网址 http://127.0.0.1:8000 后,django 首先会把协议 http、域名 127.0.0.1 和端口号 8000 去掉,此时只剩下一个空字符串,而 '' 的模式正是匹配一个空字符串,于是二者匹配,django 便会调用其对应的
views.index
函数。
.
├── Pipfile
├── Pipfile.lock
├── blog
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
├── db.sqlite3
├── firstblog
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ ├── models.py
│ ├── static
│ ├── tests.py
│ ├── urls.py # 修改的是这个
│ └── views.py
├── manage.py
注意在 blogproject\ 目录下(即 settings.py 所在的目录),原本就有一个 urls.py 文件,这是整个工程项目的 URL 配置文件。而我们这里新建了一个 urls.py 文件,且位于 blog 应用下。这个文件将用于 blog 应用相关的 URL 配置,这样便于模块化管理。不要把两个文件搞混了。
编写视图函数
第二步就是要实际编写我们的 views.index 视图函数了,按照惯例视图函数定义在 views.py 文件里:
from django.http import HttpResponse
def index(request):
return HttpResponse("欢迎访问我的博客首页!")
WEB服务器的本质就是==接收用户的http请求,也就是request
,然后根据请求内容返回相应的http响应。这个request
就是 django 为我们封装好的 HTTP 请求,它是类 HttpRequest
的一个实例。然后我们便直接返回了一个 HTTP 响应给用户,这个 HTTP 响应也是 django 帮我们封装好的,它是类 HttpResponse
的一个实例,只是我们给它传了一个自定义的字符串参数。浏览器接收到这个响应后就会在页面上显示出我们传递的内容 :欢迎访问我的博客首页!
配置项目 URL
前面建立了一个 urls.py 文件,并且绑定了 URL 和视图函数 index,还要让Django知道去找这个urls.py
才行。django 匹配 URL 模式是在 blog\ 目录(即 settings.py 文件所在的目录)的 urls.py
下的,所以我们要把 firstblog 应用下的 urls.py
文件包含到 blog\urls.py
里去,打开这个文件看到如下内容:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('', include('firstblog.urls')),
]
我们这里导入了一个 include
函数,然后利用这个函数把 firstblog 应用下的 urls.py
文件包含了进来。此外 include 前还有一个 ''
,这是一个空字符串。这里也可以写其它字符串,django 会把这个字符串和后面 include
的 urls.py
文件中的 URL 拼接。比如说如果我们这里把 '' 改成 'firstblog/',而我们在 firstblog\urls.py
中写的 URL 是 '',即一个空字符串。那么 django 最终匹配的就是 firstblog/ 加上一个空字符串,即 firstblog/。
.
├── Pipfile
├── Pipfile.lock
├── blog
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py #改的这个
│ └── wsgi.py
├── db.sqlite3
├── firstblog
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ ├── models.py
│ ├── static
│ ├── tests.py
│ ├── urls.py
│ └── views.py
├── manage.py
运行结果
运行 pipenv run python manage.py runserver
,在浏览器输入开发服务器的地址 http://127.0.0.1:8000/, 可以看到 django 返回的内容了。
欢迎访问我的博客首页!
使用 django 模板系统
写好处理 HTTP 请求和返回 HTTP 响应的视图函数,然后把视图函数绑定到相应的 URL 上。 这就是Django处理HTTP的流程。
但我们不能每次都把大段的内容传给 HttpResponse。django 对这个问题给我们提供了一个很好的解决方案,叫做模板系统。django 要我们把大段的文本写到一个文件里,然后 django 自己会去读取这个文件,再把读取到的内容传给 HttpResponse
。
添加模板
首先在我们的项目根目录(即 manage.py 文件所在目录)下建立一个名为templates
的文件夹,用来存放我们的模板。然后在templates\
目录下建立一个名为 blog
的文件夹,用来存放和 blog 应用相关的模板。在 templates\blog
目录下建立一个名为 index.html
的文件,此时你的目录结构应该是这样的:
.
├── Pipfile
├── Pipfile.lock
├── blog
├── db.sqlite3
├── firstblog
├── manage.py
└── templates
└── blog
└── index.html
在index.html
中写入:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{{ title }}</title>
</head>
<body>
<h1>{{ welcome }}</h1>
</body>
</html>
用 {{ }}
包起来的变量叫做模板变量。django 在渲染这个模板的时候会根据我们传递给模板的变量替换掉这些变量。最终在模板中显示的将会是我们传递的值。
模板写好了,还得告诉 django 去哪里找模板,在 settings.py
文件里设置一下模板文件所在的路径。在 settings.py 找到 TEMPLATES 选项,它的内容是这样的:
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [os.path.join(BASE_DIR, 'templates')], #修改成这样
'APP_DIRS': True,
'OPTIONS': {
其中 DIRS
就是设置模板的路径,在[]
中写入 os.path.join(BASE_DIR, 'templates')
这里 BASE_DIR
是 settings.py
在配置开头有定义,记录的是工程根目录 查找路径。在这个目录下有模板文件所在的目录 templates\
,于是利用os.path.join 把这两个路径连起来,构成完整的模板路径,django 就知道去这个路径下面找我们的模板了。视图函数view.py
可以改成下面这样:
from django.shortcuts import render
def index(request):
return render(request, 'blog/index.html', context={
'title': '我的博客首页',
'welcome': '欢迎访问我的博客首页'
})
调用 django 提供的 render
函数。这个函数根据我们传入的参数来构造 HttpResponse。我们首先把 HTTP 请求(request)传了进去,然后 render 根据第二个参数的值 blog/index.html 找到这个模板文件并读取模板中的内容。之后 render 根据我们传入的 context 参数的值把模板中的变量替换为我们传递的变量的值,{{ title }}
被替换成了 context 字典中 title 对应的值,同理 {{ welcome }}
也被替换成相应的值。最终,我们的 HTML 模板中的内容字符串被传递给 HttpResponse 对象并返回给浏览器(django 在 render 函数里隐式地帮我们完成了这个过程),这样用户的浏览器上便显示出了我们写的 HTML 模板的内容了。
References
[1] HelloGitHub-Team 仓库: https://github.com/HelloGitHub-Team/HelloDjango-blog-tutorial
https://mp.weixin.qq.com/s/A9RHHm6wRDsMzbMU9oShyQ
00-django | 02-处理HTTP请求的更多相关文章
- Django - 02 优化一个应用
Django - 02 优化一个应用 上一篇中我们已经创建了一个blog app,现在来用一下~ 2.1 添加第一篇blog 这个post 列表很丑陋哦,连标题都木有显示~ 2.2 自定义bl ...
- [django]windows下用Django,静态文件请求失败,出现UnicodeDecodeError
问题:windows下用Django,静态文件请求失败,出现UnicodeDecodeError:'utf-8' codec can't decode byte 0xb0 in position 1: ...
- django是怎么处理请求的
本文摘自 http://djangobook.py3k.cn/2.0/chapter03/ 我们在Django建立helloworld自定义页面中新建了站点,并能接受URL请求展示我们的页面,那Dja ...
- Django的跨域请求
一 同源策略 同源策略(Same origin policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响.可以说Web是构建在同源策略基础之 ...
- Django中Celery http请求异步处理(四)
Django中Celery http请求异步处理 本章延续celery之前的系列 1.settings配置 2.编写task jib_update_task任务为更新salt jid数据 3.url设 ...
- django允许跨域请求配置
django允许跨域请求配置 下载corsheader pip install django-cors-headers 修改setting.py中配置 在INSTALLED_APPS中增加corshe ...
- Django 02 url路由配置及渲染方式
Django 02 url路由配置及渲染方式 一.URL #URL #(Uniform Resoure Locator) 统一资源定位符:对可以从互联网上得到的资源的位置和访问方法的一种简洁的表示,是 ...
- django的跨站请求访问
一.简介 django为用户实现防止跨站请求伪造的功能,通过中间件 django.middleware.csrf.CsrfViewMiddleware 来完成.而对于django中设置防跨站请求伪造功 ...
- django解决跨域请求的问题
跨域请求可以用jsonp来解决,不过今天我发现一个很好用的包:django-cors-headers 只需要简单地配置一下就可 被请求方的setting.py中的配置如下: INSTALLED_APP ...
- 源码剖析Django REST framework的请求生命周期
学习Django的时候知道,在Django请求的生命周期中,请求经过WSGI和中间件到达路由,不管是FBV还是CBV都会先执行View视图函数中的dispatch方法 REST framework是基 ...
随机推荐
- CTF--HTTP服务--PUT上传漏洞
开门见山 1. 扫描靶机ip,发现PCS 192.168.31.48 2. 用nmap扫描靶机的开放服务和版本信息 3. 再扫描全部信息 4. 用nikto探测靶机http服务敏感信息 5. 再用di ...
- Struts2与OGNL的联系
1.Struts与OGNL的结合原理 (1)值栈: OGNL表达式要想运行就要准备一个OGNLContext对象,Struts2内部含有一个OGNLContext对象,名字叫做值栈. 值栈也由两部分组 ...
- 面试总结 | Linux后台开发不得不看的知识点(给进军bat的你!)
目录 一 自我介绍 二 面试情况 三 相关知识点汇总 1 c/c++相关 2 计算机网络 3 数据结构相关 4 数据库相关 5 操作系统 6 Linux基础知识及应用编程(后台必备!) 7 大数问题 ...
- RabbitMQ下载与安装
RabbitMQ下载与安装 先跟大家科普一下MQ和RabbitMQ MQ简介 MQ全称为Message Queue ,即消息队列 应用场景: 1.任务异步处理. 将不需要同步处理的并且耗时长的操作由消 ...
- non-local static 变量初始化顺序不确定,带来的问题
所谓static对象,其寿命从被构造出来直到程序结束为止,因此stack和heap-based对象都被排除.这种对象包括global对象.定义于namespace作用域内的对象,classes内.在函 ...
- Codeforces_711_B
http://codeforces.com/problemset/problem/711/B 比较简单,过程有点繁琐,先找一行包含那个0的行,得到和,以此填出0位置的值,然后判断这个矩阵是否符合条件. ...
- eclipse 连接sql sever
https://www.cnblogs.com/newen/p/4428541.html 和eclipse连接mysql相似,只是 String url="jdbc:sqlserver:// ...
- Guava入门使用教程
Guava入门使用教程 Guava Maven dependency In our examples, we use the following Maven dependency. <depen ...
- webpack chunkFilename 非入口文件的命名规则 [转]
官网的文档只理解了filename是主入口的文件名,chunkFilename是非主入口的文件名 filename应该比较好理解,就是对应于entry里面生成出来的文件名.比如: { entry: { ...
- Window10和Ubuntu 18.04双系统安装的引导问题解决
作为码农 首先,建议了解下grub2的启动顺序和逻辑.可以参考这篇文章,grub.cfg详解. 从执行顺序倒推,如下如果全部执行成功,则会进入grub的启动菜单:如果最后一步,没有找到grub.cfg ...