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是基 ...
随机推荐
- 前端基础JavaScript
JavaScript概述 ECMAScript和JavaScript的关系 1996年11月,JavaScript的创造者--Netscape公司,决定将JavaScript提交给国际标准化组织ECM ...
- 机器学习:没有免费午餐定理(No Free Lunch Theorem)
思考 机器学习中哪个算法好?哪个算法差呢? 下面两条线,哪个更好呢? 没有免费午餐定理 如果我们不对特征空间有先验假设,则所有算法的平均表现是一样的. 假设我们的计算机只有两个存储单元,而且每个存储单 ...
- 实验21:IPv6
九.IPv6 1.IPv6(RIP) 实验目的:熟悉IPv6的配置,并经过动态路由协议RIP,使三台路由器相互通讯设备需求:3640三台实验过程: xdbr_R1#sh runipv6 unicast ...
- LinearLayout里面的空间居中对齐
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android=&quo ...
- 9. HanLP《自然语言处理入门》笔记--9.关键词、关键句和短语提取
笔记转载于GitHub项目:https://github.com/NLP-LOVE/Introduction-NLP 9. 信息抽取 信息抽取是一个宽泛的概念,指的是从非结构化文本中提取结构化信息的一 ...
- 时序数据库 Apache-IoTDB 源码解析之文件索引块(五)
上一章聊到 TsFile 的文件组成,以及数据块的详细介绍.详情请见: 时序数据库 Apache-IoTDB 源码解析之文件数据块(四) 打一波广告,欢迎大家访问IoTDB 仓库,求一波 Star. ...
- 部署 harbor 私有仓库
安装下载依赖包 安装docker-compose 从 docker compose 发布页面下载最新的 docker-compose 二进制文件,本文以1.25.4为例 cd /opt/k8s/wor ...
- 使用Java封装一个DBUtils类(反射)
刚开始学JavaWeb时,我是调用N个setter方法将从数据库中查询出的数据封装成JavaBean的,极其繁琐. 后来了解SpringJDBC后,发现它提供的接口非常简单,然后就想自己封装一个简单的 ...
- 机器学习总结-LR(对数几率回归)
LR(对数几率回归) 函数为\(y=f(x)=\frac{1}{1+e^{-(w^{T}x+b)}}\). 由于输出的是概率值\(p(y=1|x)=\frac{e^{w^{T}x+b}}{1+e^{w ...
- POJ_2593_DP
http://poj.org/problem?id=2593 和2479一样. #include<iostream> #include<cstdio> #define MIN ...