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是基 ...
随机推荐
- keras模型可视化
#keras.utils.vis_utils模块提供了画出Keras模型的函数(keras版本2.0.2以上)pip install graphviz pip install pydotplus im ...
- Centos与Ubuntu
共同点 1.两个系统都分别有桌面系统与服务器系统,不过ubuntu的桌面从外观上来看要比centos的漂亮 不同点 1.centos中新建的普通用户是没有sudo权限的,如果想让普通用户拥有sudo权 ...
- wireshark简单实用教程
转自:https://jingyan.baidu.com/article/c35dbcb0866b698916fcbc81.html wireshark是非常流行的网络封包分析软件,功能十分强大.可以 ...
- Python变量、方法、类的命名规则
1. 变量命名总结: - 1.单下划线开头变量:protected - 2.双下划线开头变量:private - 3.双下划线开头,双下划线结尾:系统内置变量 2. 函数命名总结: - 1.私有方法: ...
- Nginx(二) 常用配置
全局配置段 # 允许运行nginx服务器的用户和用户组 user www-data; # 并发连接数处理(进程数量),跟cpu核数保存一致: worker_processes auto; # 存放 n ...
- Ubuntu 入门笔记(1)
在阿里云上申请了一个云服务器,开始学习Linux.我选择的是Ubuntu 14.04 ,在登录时就绕了我好长时间,输入用户名是有显示的,但是输入密码就没有反应了,查找了之后才发现原来这是Ubuntu ...
- 并发队列之PriorityBlockingQueue
这一篇说一下PriorityBlockingQueue,引用书中的一句话:这就是带优先级的无界阻塞队列,每次出队都返回优先级最高或者最低的元素(这里规则可以自己制定),内部是使用平衡二叉树实现的,遍历 ...
- mybatis缓存,从一个“灵异”事件说起
刚准备下班走人,被一开发同事叫住,让帮看一个比较奇怪的问题:Mybatis同一个Mapper接口的查询方法,第一次返回与第二次返回结果不一样,百思不得其解! 问题 Talk is cheap. Sho ...
- HDU_1394_线段树
http://acm.hdu.edu.cn/showproblem.php?pid=1394 线段树入门题,每次读入一个数,就寻找在树中比它大的值的个数,然后更新树,把个数相加就是逆序数,每移动一个数 ...
- Centos 7 x64 系统初始化
前言 Hi,小伙伴们,系统初始化是运维工作中重要的一环,它能有效的提升工作效率,并且是标准化规范化的前提:它能省去要用时再去下载的麻烦,另外,还可以避免因未初始化引起的一些故障问题,可谓好处多多.系统 ...