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是基 ...
随机推荐
- 基于playcanvas的3d模型展示
1.使用基于playcanvas的离线编辑器制作模型效果 2.使用基于playcanvas的开发包读取编辑好的3d模型进行在线3d展示 效果如下:
- php--->使用callable强制指定回调类型
php 使用callable强制指定回调类型 如果一个方法需要接受一个回调方法作为参数,我们可以这样写 <?php function dosth($callback){ call_user_fu ...
- 关于selenium自动化元素定位问题解决的几种方法
遇到了元素定位问题和定位到后无法执行点击操作等,闲话少说,直奔主题: 1.元素定位不到一般有如下3种情况,大家如果遇到了可以对号入座哈 a.查找的元素不在当前窗口中 解决方法:使用driver.swi ...
- CTF--HTTP服务--SSI注入
开门见山 1. 扫描靶场ip,发现VM 192.168.31.160 2. 扫描主机服务信息和服务版本 3. 快速扫描靶场全部信息 4. 探测开放的http的敏感信息 5. 再用dirb扫描敏感页面 ...
- nmap详解之基础概述
概述 nmap是一个网络探测和安全扫描程序,系统管理者和个人可以使用这个软件扫描大型的网络,获取那台主机正在运行以及提供什么服务等信息.nmap支持很多扫描技术,例如:UDP.TCP connect( ...
- Docker三剑客之swarm
简介 swarm是一种docker集群管理工具,跟三剑客前两者不同的是:compose是一种统一编排的工具,machine是一种远程控制工具,swarm则是将多个docker主机映射成一个docker ...
- BeautifulSoup标签定位方法总结
首先说明一下两个基本函数 .find() 和 .findAll(). find()返回第一个符合要求的标签 findAll()返回一个由所有符合要求的标签组成的列表.除此之外基本相同. 0.直接定位 ...
- Web 开发工具类(3): JsonUtils
JsonUtils 整合了一些对Json的相关操作: package com.evan.common.utils; import java.util.List; import com.fasterxm ...
- tricky c++ new(this)
题目如下:问下列代码的打印结果为0吗? #include <stdlib.h> #include <iostream> using namespace std; struct ...
- LintCode 433. 岛屿的个数(Number of Islands)
LintCode 433. 岛屿的个数(Number of Islands) 代码: class Solution: """ @param grid: a boolean ...