当前位置: 首页 > wzjs >正文

湘潭做网站问下磐石网络品牌推广软文

湘潭做网站问下磐石网络,品牌推广软文,重庆装修工人哪里找,九江市做网站的公司在开发过程中,可能会遇到一些框架的报错,比如http方法不允许、中间件检查不通过、路由匹配错误等,此类情况下因为报错是框架层面报的,这时候就有必要在框架的源代码层面打断点从而定位问题了。而源代码层面的断点打在哪&#xff0…

在开发过程中,可能会遇到一些框架的报错,比如http方法不允许、中间件检查不通过、路由匹配错误等,此类情况下因为报错是框架层面报的,这时候就有必要在框架的源代码层面打断点从而定位问题了。而源代码层面的断点打在哪,就需要了解清楚本文说的一些流程。

1、服务启动过程

我们最熟悉的服务启动方式就是这个runserver了:

python3 manange.py runserver

先讲下runserver的代码内容。

在django的源码里,有这样一个目录django/core/managemtn/commands/,这个目录下有很多我们熟悉的文件,比如runserver.py、makemigrations.py、migrate.py等。

这些就是python3 manange.py --help显示的命令行对应的处理程序。

我们也可以在这里增加自定义的脚本,从而实现自定义命令。

我们看下runserver.py里的handle函数,这是每个命令的入口函数。

# 启动过程中的函数调用
def handle()self.run()self.inner_run()handler = self.get_handler()run(handler)    # 这里的run是引自django.core.servers.basehttp  # 先看下这个run()函数
# django/core/servers/basehttp.py
def run(addr,port,wsgi_handler):# 绑定IP、端口server_address = (addr, port)# 初始化http服务器httpd = httpd_cls(server_address, WSGIRequestHandler, ipv6=ipv6)# 设置请求处理的函数httpd.set_app(wsgi_handler)# 启动httpd.serve_forever()# 其中这个请求处理的函数handler就是self.get_handler()获取的。def get_handler()get_internal_wsgi_application()from django.conf import settingsapp_path = getattr(settings, "WSGI_APPLICATION")return import_string(app_path)
# 这个handler是在setting文件里通过WSGI_APPLICATION参数指定的。# 比如我项目的setting文件里
WSGI_APPLICATION = "application.wsgi.application"
# 这是一个路径,可以通过import导入的,从项目根目录下顺着找,找到这样一个文件# {项目根目录}/application/wsgi.py
import os
from django.core.wsgi import get_wsgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'application.settings')
os.environ["DJANGO_ALLOW_ASYNC_UNSAFE"] = "true"
application = get_wsgi_application()
# 在我的项目里没有做过多自定义,调用django提供的get_wsgi_application,
# 这个函数返回的内容就是handler了# django/core/wsgi.py
def get_wsgi_application():return WSGIHandler() # 至此,我们找到了handler的真面目,就是这个WSGIHandler()

上面只讲了下django自带的runserver的启动过程,在生产环境下,我们会看到用比如uwsgi、gunicorn等命令来启动服务,其实原理都差不多,最主要的就是给这些http服务传递一个请求的入口函数。

再扩展一下,django其实是支持两类服务器,同步服务器(wsgi)和异步服务器(asgi),我们上面介绍的uwsgi这些都是同步服务器,异步服务器比如uvicorn,此处就不介绍了,感兴趣自行研究。

2、请求处理过程

浏览器发起一个http请求,最后如何转到我们写的一个view函数上呢,继续挖一挖。

首先请求的处理函数是这个WSGIHandler()。

# django.core.handlers.wsgi.py
# WSGIHandler()这个类继承自BaseHandler
# 其自身的代码很少,主要的几个方法都在BaseHandler里class WSGIHandler(base.BaseHandler):# 定义一个初始化HttpRequest的类,# 这个类的作用就是将http请求封装成django标准的HttpRequest,方便后续使用request_class = WSGIRequest# 初始化方法# 调用self.load_middleware()加载setting文件里定义的中间件def __init__(self, *args, **kwargs):super().__init__(*args, **kwargs)self.load_middleware()# 请求到达时进入__call_函数处理# 先用request_class把http请求封装成HttpRequest# 具体的处理逻辑就在BaseHandler的get_response函数里了def __call__(self, environ, start_response):request = self.request_class(environ)response = self.get_response(request)return response# django.core.handlers.base.py
# 下面就是BaseHandler的get_response函数
# 通过调用self._middleware_chain函数,拿到响应结果
def get_response(self, request):set_urlconf(settings.ROOT_URLCONF)response = self._middleware_chain(request)# 这个self._middleware_chain其实就是_get_response
# 两者是在load_middleware函数里绑定的,主要还是区分同步和异步,我们本篇只说同步服务器的情况
# get_response = self._get_response_async if is_async else self._get_response# 核心的处理函数_get_response
def _get_response(self, request):# resolve_request:解析路由,获得请求对应的处理函数callback, callback_args, callback_kwargs = self.resolve_request(request)# 先依次应用中间件里的处理for middleware_method in self._view_middleware:response = middleware_method(request, callback, callback_args, callback_kwargs)# 再执行callback处理函数,就是我们写的view视图函数wrapped_callback = self.make_view_atomic(callback)response = wrapped_callback(request, *callback_args, **callback_kwargs)# 返回处理结果return response# 关于resolve_request如何通过路由表找到对应视图函数的解析,可以参考本系列的路由相关内容

至此,http请求的处理过程基本清晰了,核心逻辑在_get_response中,主要包含解析路由表–应用中间件–执行视图函数–返回结果这几个步骤。
所以后续再遇到比如路由不到自己预想的函数,就可以跟一下resolve_request等等。

3、django中的HttpRequest和HttpResponse

在django框架中,请求在内部处理的流程如下:

  1. 客户端发送请求 → Django 创建 HttpRequest 对象,封装所有请求数据。
  2. 视图函数处理 → 开发者通过 request 获取数据,处理后生成 HttpResponse
  3. 服务器返回响应 → Django 将 HttpResponse 转换为符合 HTTP 协议的响应,发送给客户端。

为什么会出现HttpRequestHttpResponse呢?

主要是为了避免开发者处理底层协议细节,简化数据访问。

如果没有它们,开发者需要手动解析原始 HTTP 数据,代码会变得复杂且难以维护。

学习这两个类的目的是什么呢?

对于HttpRequest,主要是为了取出请求里的数据,比如header信息、表单信息、参数信息等,因此要搞清楚这些信息存在HttpRequest的哪些属性里。

对于HttpResponse,因为是开发者要封装的,要搞清楚如何将自己要返回的数据给到HttpResponse。

HttpRequest

httpReqeust的属性有:

属性类型说明
methodstrHTTP 请求方法(GET/POST/PUT/DELETE等)
GETQueryDict包含所有GET参数的类字典对象
POSTQueryDict包含所有POST参数的类字典对象
FILESMultiValueDict包含所有上传文件的类字典对象
COOKIESdict包含所有cookies的字典
METAdict包含所有HTTP头信息的字典
pathstr请求的完整路径(不包括域名和查询参数)
path_infostr类似于path,但在某些服务器配置下可能不同
bodybytes原始HTTP请求体(字节字符串)
headersHttpHeadersDjango 3.2+引入,更友好的headers访问方式
sessionSessionStore可读写的类字典对象,表示当前会话
userUser表示当前登录用户的User对象

属性说明:

1、取参数,get方法的参数和post方法的参数分别存在request.GET和request.POST中,后端在取参数的时候要对判断http方法。

def example_view(request):if request.method == "POST":username = request.POST.get("username")  # 获取 POST 参数file = request.FILES.get("avatar")       # 获取文件elif request.method == "GET":username = request.GET.get("username")

2、特殊情况下,取参需要使用body中的内容,注意body属于原始字符串,后端使用前需要解码。

import json
data = json.loads(request.body.decode('utf-8'))

3、META部分包含了所有HTTP头信息,请求中的任何 HTTP 头都会被转换为 META 键,方法是将所有字符转换为大写字母,用下划线代替任何连字符,并在名称前加上 HTTP_ 前缀,例如,一个名为 X-Name 的头将被映射到 META 键 HTTP_X_NAME。

在这里插入图片描述

def example_view(request):name = request.META['HTTP_X_NAME']

httpReqeust还提供了一些获取常用属性的方法,比如客户端的主机名、端口等

方法返回类型说明
get_full_path()str返回path + 查询字符串
is_secure()bool如果请求是通过HTTPS发出的返回True
get_host()str获取请求的主机名
get_port()str获取请求的端口号
build_absolute_uri(location)str返回location的绝对URI
get_signed_cookie(key)str获取签名cookie的值
read(size=None)bytes从请求体中读取数据

httpResponse

学习httpResponse就是搞清楚如何构造一个django支持的响应。先看这个类的构造函数。

# HttpResponse是在view处理阶段要自行构造的,因此需要搞清楚要传的参数
class HttpResponse(HttpResponseBase):def __init__(self,content=b'',content_type=None,status=None,reason=None,charset=None):

可以看出我们要返回的内容主要是放在content属性里,以字节的格式返回。

def my_view(request):return HttpResponse('ok')# 最常见的比如就是把'ok'赋值给content返回。

除了上面说的简单的字符串,HttpResponse还支持以下属性设置。

属性类型说明
contentbytes响应内容(字节形式)
charsetstr响应编码(如 ‘utf-8’)
status_codeintHTTP 状态码(如 200, 404)
reason_phrasestr状态码描述(如 “OK”, “Not Found”)
headersHttpHeaders响应头(类字典对象)
cookiesSimpleCookie用于设置 Cookie 的对象

还可以通过内置的函数,进行属性设置和数据写入。

方法说明
set_cookie()设置 Cookie
delete_cookie()删除 Cookie
write(content)写入响应内容(用于流式响应)
setdefault(key, value)设置默认响应头

HttpResponse常用的子类如下,主要是对特定场景做了定制化,减少开发工作量。

子类说明
JsonResponse返回 JSON 响应(自动设置 Content-Type)
FileResponse返回文件下载响应
StreamingHttpResponse流式响应(大文件处理)
HttpResponseRedirect302 重定向响应
HttpResponsePermanentRedirect301 永久重定向
HttpResponseNotFound404 响应
HttpResponseForbidden403 响应
HttpResponseBadRequest400 响应

4、DRF中的Request和Response

Request

在DRF中,基于httpReqeust做了扩展,封装成了Requests类。

从DRF的Request获取数据和django的HttpRequest获取数据有哪些区别:

1、data属性,支持所有的文件输入和非文件输入,支持除POST之外的HTTP方法的内容,这意味着你可以访问PUT和PATCH请求的内容。(在djanog中读取文件需要读取request.FILES,非文件需要读取request.GET或request.POST或request.body)。

2、query_params属性,就是django中的request.GET。

3、增加了认证支持(此处不展开)。

DRF是在请求的哪个步骤引入了Request呢?

# 首先我们知道请求经过self.resolve_request(request)解析出了处理函数。
# 对于drf中基于类的视图中,通常会调用类的as_view()函数
# 而as_view函数返回的就是该类的dispatch()函数。
# 也就是resolve_request之后的函数处理入口就是这个类的dispatch函数。# rest_framework/views.py
class APIView(View):def dispatch(self, request, *args, **kwargs):request = self.initialize_request(request, *args, **kwargs)def initialize_request(self, request, *args, **kwargs):parser_context = self.get_parser_context(request)return Request(request,parsers=self.get_parsers(),authenticators=self.get_authenticators(),negotiator=self.get_content_negotiator(),parser_context=parser_context)
# 从上面代码中可以看出,Request是在dispatch函数中引入的。
# 而DRF中的viewset、modelViewSet都是继承自APIView,都是复用的这部分代码。
# 所以在DRF中只要你的视图是基于APIView、viewset、modelViewSet,
# 那么你用的request大概率就是Request实例,否则就还是django的httpRequest.

Response

对于DRF的响应类Response,如何构造返回实例。

class Response(SimpleTemplateResponse)def __init__(self, data=None, status=None,template_name=None, headers=None,exception=False, content_type=None):

可以看出数据主要赋值给data进行返回。data要求是序列化后的数据,不能是类实例。

http://www.dtcms.com/wzjs/80775.html

相关文章:

  • 试用虚拟主机不能创建网站西安今天刚刚发生的新闻
  • 网站制作计划磁力宅在线搜种子
  • 优化推广网站推荐代码优化
  • 灵犀科技+网站开发佼佼者搜索引擎优化指的是什么
  • 医药做网站杭州网站推广优化
  • 环球网广西疫情最新动态重庆百度seo
  • 秦皇岛做网站优化公司友情链接的形式有哪些
  • php网站好吗全国知名网站排名
  • 秦皇岛建设信息网站画质优化app下载
  • 做地方门户网站赚钱吗百度大数据
  • 什么网站可以兼职做设计百度站长平台工具
  • 站酷官网宣传推广方案范文
  • 配资网站建设多少钱电商怎么推广自己的产品
  • 泉州市网站制作企业买卖链接网
  • 做会展网站的关键词百度热门关键词排名
  • zenm自己做网站北京网络推广外包公司排行
  • 襄阳哪里做网站链接交易网
  • 做网站带来好处5118
  • 手机网站后台源码怎样推广产品
  • 如果是创建的网站南京搜索引擎推广优化
  • 开锁都在什么网站做如何自己建一个网站
  • 1元云购网站怎样建设网站服务费一年多少钱
  • 百度网站建设费用怎么做账电工培训机构
  • 新开传奇网站sf营销效果分析怎么写
  • wordpress下载最新seowhy论坛
  • 网站备案注销下载强力搜索引擎
  • 网站建设前台功能上海网站seo策划
  • wordpress导航插件陕西seo关键词优化外包
  • 网站建设中的技术问题网络推广员为什么做不长
  • 天猫网站做的比京东好新站seo优化快速上排名