凯发真人娱乐

详解django请求与响应:深入理解web http交互的核心机制 -凯发真人娱乐

2023-10-19,,

本文深入探讨了 django 中的请求与处理,从 django 请求和响应的基础知识、生命周期,到 httprequest 和 httpresponse 对象的详细介绍。同时,讨论了 django 的视图和请求、响应处理,以及安全性和异步处理的考虑。最后,对比了 django 与 flask、fastapi 等框架在请求响应处理上的异同。无论您是 django 新手还是有经验的开发者,这篇文章都能帮助您更好地理解 django 的请求和响应处理。

1. django 请求httprequest和响应httpresponse的基础知识

在web应用程序中,请求和响应模式是非常重要的概念。当用户在浏览器地址栏输入一个url或者点击某个链接时,会向服务器发送一个请求。服务器处理完这个请求后,会返回一个响应给浏览器。这就是典型的http请求-响应模式。

1.1 django 的请求对象httprequest

在 django 中,当一个 http 请求到达 django 应用时,它首先会被某个urlconf文件转化为一个 httprequest 对象。这个对象包含了这次http请求的所有相关的信息。

def view(request):
# request 是一个 httprequest 对象
print(request.method) # 输出请求方法,比如 "get" 或 "post"

1.2 django 的响应对象httpresponse

django的视图必须返回一个 httpresponse 对象。这个对象表示服务器给客户端(通常是浏览器)的响应。这个 httpresponse 对象会被转化为一个 http 响应,然后被发送到客户端。

from django.http import httpresponse
def view(request):
# 创建一个 httpresponse 对象
response = httpresponse("hello, world!")
return response # 这个响应将会被发送给客户端

1.3 http 方法get/post

http 方法是客户端可以对服务器发出的一种 "指令"。最常见的方法包括 get 和 post。

get: 通常用于获取(或查询)资源信息。
post: 通常用于更新资源信息。

在 django 中,你可以通过 httprequest 对象的 method 属性来访问这个请求的方法:

def view(request):
print(request.method) # 输出请求方法,比如 "get" 或 "post"

2. django 请求的生命周期

一旦django应用收到了一个http请求,它会经历一系列的阶段,这些阶段共同构成了请求的生命周期。以下是这个过程的详述:

2.1 请求到达

当一个请求到达django应用时,它首先会被wsgi服务器接收。django项目被wsgi服务器(如gunicorn或uwsgi)作为一个python应用程序运行。

# 这是一个简单的wsgi应用的示例,当然,实际的django wsgi应用更加复杂
def application(environ, start_response):
start_response('200 ok', [('content-type', 'text/plain')])
return [b"hello world!"]

2.2 url 解析

接下来,请求会被送到url解析器,url解析器会根据urlconf模块中定义的url模式列表对url进行匹配。url模式是使用python的正则表达式来定义的。

# urls.py
from django.urls import path from . import views urlpatterns = [
path('articles/2003/', views.special_case_2003),
path('articles//', views.year_archive),
]

2.3 视图处理

一旦url解析器找到了匹配的模式,它会调用与该模式关联的视图函数,并将httprequest对象和从url中提取的任何参数传递给该视图。

# views.py
from django.http import httpresponse def special_case_2003(request):
return httpresponse("special case for 2003") def year_archive(request, year):
return httpresponse(f"articles for {year}")

2.4 响应返回

视图函数处理完请求后,会创建一个httpresponse对象并返回。这个响应对象会经过中间件的一系列处理,最终会被转换为一个http响应,然后发送给客户端。

# 视图函数返回一个响应
def view(request):
response = httpresponse("hello, world!")
return response # 这个响应将会被发送给客户端

3. django httprequest详述

在 django 中,所有的 http 请求都被封装在 httprequest 对象中。下面我们将详细介绍 httprequest 对象的常见属性和方法。

3.1 httprequest 属性

httprequest 对象有很多属性,可以帮助我们获取 http 请求的详细信息。以下是一些最常用的属性:

path: 一个字符串,表示请求的路径,不包括域名或者站点根 url 的路径。

method: 一个字符串,表示 http 请求的方法。常见的值有 "get","post" 等。

get: 一个类似字典的对象,包含所有的 get 参数。

post: 一个类似字典的对象,包含所有的 post 参数。

cookies: 一个字典,包含所有的 cookie。键和值都为字符串。

files: 一个类似字典的对象,包含所有的上传文件。

user: 一个表示当前用户的 user 对象。如果用户当前未登录,这将是一个 anonymoususer 实例。

def view(request):
# 打印一些 httprequest 属性的值
print(request.path) # 输出请求路径,比如 "/my-path/"
print(request.method) # 输出请求方法,比如 "get"
print(request.get) # 输出 get 参数,比如
print(request.user) # 输出当前用户,如果用户未登录,将输出 anonymoususer

3.2 httprequest 方法

除了属性,httprequest 对象还有一些有用的方法:

is_ajax(): 如果请求是通过 xmlhttprequest 发出的,返回 true。

is_secure(): 如果请求是通过 https 发出的,返回 true。

is_authenticated(): 如果当前用户已经登录,返回 true。

def view(request):
# 打印一些 httprequest 方法的返回值
print(request.is_ajax()) # 如果请求是 ajax 请求,输出 true
print(request.is_secure()) # 如果请求是 https 请求,输出 true
print(request.is_authenticated()) # 如果当前用户已登录,输出 true

4. django 视图view和请求httprequest处理

在 django 中,视图是一个 python 函数,用于接收一个 web 请求并返回一个 web 响应。这个响应可以是 web 页面的 html 内容,重定向,404 错误,xml 文档,图像,或者任何其他类型的内容。简单来说,django 视图的任务就是接受一个 web 请求并返回一个 web 响应。

4.1 创建视图

在 django 中,创建一个视图只需要定义一个 python 函数,这个函数需要接受一个 httprequest 对象作为第一个参数,然后返回一个 httpresponse 对象。如下所示:

from django.http import httpresponse
def hello(request):
return httpresponse("hello, world!")

在这个例子中,hello 函数就是一个视图,它接收一个 httprequest 对象,然后返回一个包含 "hello, world!" 的 httpresponse 对象。

4.2 视图参数

视图函数的第一个参数总是 httprequest 对象,而从 url 中捕获的参数将作为额外的参数传递给视图函数。例如:

from django.http import httpresponse
def hello(request, name):
return httpresponse(f"hello, {name}!")

在这个例子中,hello 视图接受两个参数:一个 httprequest 对象和一个 name 字符串。你可以在 urlconf 中定义如何从 url 中提取这个 name 参数。

4.3 httpresponse 对象

视图必须返回一个 httpresponse 对象。httpresponse 类在 django.http 模块中定义,表示一个 http 响应,或者说是一个服务器给客户端的回应。

httpresponse 对象通常包含文本内容,可以是 html,也可以是 json。除了文本内容,你还可以通过设置 httpresponse 的不同属性(比如 content_typestatus)来控制其他 http 响应的参数。

from django.http import httpresponse
def hello(request):
response = httpresponse("hello, world!", content_type="text/plain", status=200)
return response

5. django httpresponse详述

httpresponse 对象是 django 视图中返回的结果对象,它是由 django 视图返回并通过 django 框架传送给客户端的。

5.1 httpresponse 属性

httpresponse 对象有一些常用的属性,我们可以使用它们来定义我们的响应。以下是一些常见的属性:

content: 响应的主体内容,通常为一个字符串或字节串。

status_code: http 状态码,如 200、404 等。

content_type: 响应的 mime 类型,默认为 'text/html'。

from django.http import httpresponse
def view(request):
response = httpresponse()
response.content = "hello, world!"
response.status_code = 200
response.content_type = 'text/plain'
return response

5.2 httpresponse 方法

除了属性,httpresponse 对象还有一些有用的方法:

set_cookie(key, value, max_age=none, expires=none): 设置一个 cookie。key 是 cookie 的名字,value 是 cookie 的值。max_age 是 cookie 的最大生存时间,单位是秒。expires 是 cookie 的过期时间,是一个 datetime 对象或 unix 时间戳。

delete_cookie(key): 删除一个 cookie。

from django.http import httpresponse
def view(request):
response = httpresponse("hello, world!")
response.set_cookie('my_cookie', 'cookie_value', max_age=60*60*24) # 设置一个一天后过期的 cookie
return response

5.3 特殊的 httpresponse 对象

除了普通的 httpresponse 对象,django 还提供了一些特殊的 httpresponse 对象,用于生成特定的响应。例如:

jsonresponse: 这个响应对象接收一个字典或列表,并返回一个 application/json 类型的响应。

httpresponseredirect: 这个响应对象用于生成一个重定向响应。

httpresponsenotfound: 这个响应对象用于生成一个 404 错误响应。

from django.http import jsonresponse, httpresponseredirect, httpresponsenotfound
def view_json(request):
return jsonresponse({'key': 'value'}) # 返回一个 json 响应 def view_redirect(request):
return httpresponseredirect('/another-url/') # 重定向到另一个 url def view_404(request):
return httpresponsenotfound('') # 返回一个 404 错误

6. django 视图view和httpresponse响应处理

在 django 中,视图是 web 请求的主要处理者,同时也负责构建和返回响应。视图接收 httprequest 对象作为参数,生成 httpresponse 对象作为返回值。我们已经详细讨论了 httprequest 和 httpresponse,现在我们来看看如何在视图中处理它们。

6.1 处理请求

处理请求主要是提取 httprequest 对象的数据,然后根据这些数据执行相应的逻辑。

def view(request):
# 获取 get 请求的参数
name = request.get.get('name', 'guest')
# 根据请求参数执行逻辑
message = f"hello, {name}!"
return httpresponse(message)

在这个例子中,我们从 get 请求中获取 'name' 参数,然后用它来生成一条欢迎消息。

6.2 构建响应

构建响应主要是创建 httpresponse 对象,然后填充其内容。

def view(request):
# 创建 httpresponse 对象
response = httpresponse()
# 填充响应内容
response.content = "hello, world!"
response.status_code = 200
response['content-type'] = 'text/plain'
return response

在这个例子中,我们创建了一个 httpresponse 对象,然后设置了其内容、状态码和 content-type 头。

6.3 快捷方式

在 django 视图中,我们经常需要做一些常见的操作,比如渲染一个模板,重定向到另一个 url,或者返回一个 404 错误。为了简化这些操作,django 提供了一些快捷方式。

from django.shortcuts import render, redirect, get_object_or_404
from .models import mymodel def view(request):
# 渲染一个模板
context = {'key': 'value'}
return render(request, 'my_template.html', context) def redirect_view(request):
# 重定向到另一个 url
return redirect('/another-url/') def detail_view(request, pk):
# 获取一个对象或返回 404 错误
obj = get_object_or_404(mymodel, pk=pk)
return render(request, 'detail.html', {'obj': obj})

7. django 请求和响应的安全性考虑

在处理 web 请求和生成响应时,安全性是一个非常重要的考虑因素。幸运的是,django 提供了一些内置的工具和技术来帮助我们增加应用程序的安全性。

7.1 csrf 保护

跨站请求伪造(csrf)是一种攻击方式,攻击者可以伪造用户的请求。django 提供了 csrf 保护机制,可以在处理 post 请求时自动检查 csrf 令牌。

from django.views.decorators.csrf import csrf_exempt
@csrf_exempt  # 用这个装饰器来禁用 csrf 保护
def my_view(request):
# view code here...

在大多数情况下,你应该让 django 自动处理 csrf 保护。但是在某些情况下,你可能需要禁用它,比如上面的例子。

7.2 安全的数据存储

当你在处理请求时接收到敏感信息,如密码,你应该使用 django 提供的安全方法来存储这些信息。

from django.contrib.auth.hashers import make_password
def register(request):
password = request.post['password']
hashed_password = make_password(password) # 使用哈希函数来安全存储密码
# save hashed_password to database...

7.3 http 响应头的安全设置

django 提供了一些设置,你可以使用它们来增加 http 响应头的安全性,如 secure_content_type_nosniffsecure_browser_xss_filter。你可以在你的 django 设置中配置它们。

# settings.py
secure_content_type_nosniff = true
secure_browser_xss_filter = true

7.4 用户输入的安全处理

永远不要信任用户输入的数据。你应该始终对用户输入的数据进行清洗和验证。

from django.core.exceptions import validationerror
def view(request):
comment = request.post['comment']
if len(comment) > 100:
raise validationerror("comment is too long!")
# save comment to database...

8. django 异步请求和响应

django 3.1 引入了异步视图和中间件支持,这意味着你可以使用 python 的 asyncawait 关键字来处理异步任务。这对于处理 i/o 绑定任务或其他可以从并发执行中受益的任务非常有用。

8.1 异步视图

创建异步视图的方式与创建同步视图非常相似,但是你需要将视图函数定义为 async def 函数,然后在函数体中使用 await 关键字。

from django.http import jsonresponse
async def async_view(request):
data = await get_data() # 假设 get_data 是一个异步函数
return jsonresponse(data)

在这个例子中,get_data 是一个异步函数,我们使用 await 关键字来调用它。当 django 等待 get_data 完成时,它可以释放服务器资源来处理其他请求。

8.2 异步中间件

你也可以创建异步中间件,它可以处理进入视图之前或离开视图之后的请求和响应。

class simplemiddleware:
async def __call__(self, request, get_response):
response = await get_response(request)
return response

在这个例子中,simplemiddleware 是一个异步中间件,它在处理请求之前和之后没有做任何事情,只是简单地将请求传递给下一个中间件或视图。

8.3 数据库操作

在 django 的异步视图或中间件中,你不应该执行同步的数据库操作,因为这可能会阻塞事件循环。你应该使用 django 提供的 asgiref.sync.sync_to_async 函数将同步的数据库操作包装到一个线程中。

from asgiref.sync import sync_to_async
from django.contrib.auth.models import user async def async_view(request):
get_user = sync_to_async(user.objects.get)
user = await get_user(id=1)
return jsonresponse({'username': user.username})

在这个例子中,我们使用 sync_to_async 函数将 user.objects.get 包装到一个线程中,然后在异步视图中使用 await 关键字来调用它。

当然,接下来我们就来比较一下 django 与其他主流 python 框架(如 flask 和 fastapi)在请求和响应处理上的异同。

总结. django 与其他主流 python 框架在请求响应部分的比较

9.1 django vs flask

flask 是另一个流行的 python web 框架,相比 django,flask 是一个更为轻量级的框架,具有更高的定制性。

请求对象: flask 的 request 对象和 django 的 httprequest 对象在许多方面是相似的,但 flask 的 request 对象在语法上更为简洁。在 flask 中,你可以直接通过 request.form['key'] 来访问 post 参数,而在 django 中,你需要使用 request.post.get('key')

响应对象: flask 允许你直接从视图返回字符串,然后自动将其转化为 response 对象,而 django 则需要你显式地创建一个 httpresponse 对象。

url 参数: flask 提供了一种简洁的方式来在 url 中定义参数,如 @app.route('/user/'),而在 django 中,你需要在 urls.py 中使用正则表达式来定义 url 参数。

# flask
@app.route('/user/')
def show_user_profile(username):
# show the user profile for that user
return 'user %s' % username # django
from django.urls import path def show_user_profile(request, username):
# show the user profile for that user
return httpresponse('user %s' % username) urlpatterns = [
path('user//', show_user_profile),
]

9.2 django vs fastapi

fastapi 是一个新兴的 python web 框架,它的特色是快速、简单和高性能,而且内建对异步编程的支持。

类型检查: fastapi 支持 python 的类型检查,你可以在参数中直接定义类型,fastapi 会自动进行数据验证。而在 django 中,你需要自己验证数据并处理错误。

异步编程: 虽然 django 3.1 开始支持异步视图和中间件,但是 fastapi 在异步编程方面的支持更为完善。你可以在 fastapi 中使用 asyncawait 关键字来定义异步的路径操作函数,而在 django 中,你可能需要使用 asgiref.sync.sync_to_async 来包装数据库操作。

自动文档: fastapi 可以根据你的代码自动生成 api 文档,这可以帮助你更好地测试和调试你的 api。而在 django 中,你需要使用如 drf 的第三方库或手动编写 api 文档。

# fastapi
from fastapi import fastapi app = fastapi() @app.get("/items/{item_id}")
async def read_item(item_id: int):
return {"item_id": item_id}

总的来说,django、flask 和 fastapi 都是优秀的 python web 框架,它们各有各的优点。选择哪一个取决于你的项目需求,以及你更倾向于使用哪种编程范式。

如有帮助,请多关注

个人微信公众号:【python全视角】

teahlead_krischang,10 年的互联网和人工智能从业经验,10年 技术和业务团队管理经验,同济软件工程本科,复旦工程管理硕士,阿里云认证云服务资深架构师,上亿营收ai产品业务负责人。

详解django请求与响应:深入理解web http的核心机制的相关教程结束。

网站地图