1. 简述Http协议? - 超文本传输协议 - 特点: - 无状态,请求响应之后,再次发起请求时,不认识。 - 短连接,一次请求和一次响应就断开连接。 - 格式: - GET请求:输入地址回车:https://passport.jd.com/new/login.aspx?ReturnUrl=https%3A%2F%2Fwww.jd.com%2F 请求由两部分组成:请求头和请求体,请求头和请求体通过\r\n\r\n分割,请求头和请求头之间通过\r\n分割。 """GET /new/login.aspx?ReturnUrl=https%3A%2F%2Fwww.jd.com%2F http1.1\r\nUser-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36\r\nHost:jd.com\r\n\r\n""" 响应由两部分组成:响应头和响应体, b'HTTP/1.1 200 OK\r\nDate: Mon, 05 Nov 2018 01:15:31 GMT\r\nServer: Apache\r\nLast-Modified: Tue, 12 Jan 2010 13:48:00 GMT\r\nETag: "51-47cf7e6ee8400"\r\nAccept-Ranges: bytes\r\nContent-Length: 81\r\nCache-Control: max-age=86400\r\nExpires: Tue, 06 Nov 2018 01:15:31 GMT\r\nConnection: Keep-Alive\r\nContent-Type: text/html\r\n\r\n <html><head> .... </html>' - POST请求: 请求由两部分组成:请求头和请求头 """POST /new/login.aspx?ReturnUrl=https%3A%2F%2Fwww.jd.com%2F http1.1\r\nUser-Agent:Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36\r\nHost:jd.com\r\n\r\nusername=haoxu666&password=123""" 响应: b'HTTP/1.1 200 OK\r\nDate: Mon, 05 Nov 2018 01:15:31 GMT\r\nServer: Apache\r\nLast-Modified: Tue, 12 Jan 2010 13:48:00 GMT\r\nETag: "51-47cf7e6ee8400"\r\nAccept-Ranges: bytes\r\nContent-Length: 81\r\nCache-Control: max-age=86400\r\nExpires: Tue, 06 Nov 2018 01:15:31 GMT\r\nConnection: Keep-Alive\r\nContent-Type: text/html\r\n\r\n用户名或密码错误' 2. 你了解的请求头都有什么? - User-Agent,设备信息。 - Host,当前访问的主机名称。 - referrer,做防盗链。 - Content-Type: .... 3. 你了解的请求方式有哪些? - GET/POST/PUT/PATCH/DELETE/OPTIONS 4. django请求的生命周期/浏览器上输入 http://www.oldboyedu.com 地址回车发生了什么? - 浏览器输入:http://www.oldboyedu.com 回车 - DNS解析,将域名解析成IP。 - 浏览器(socket客户端),根据IP和端口(80)创建连接,发送请求。 - 服务端接收请求 - 实现了wsgi协议的模块,如:wsgiref接收到用户请求。 - 然后将请求转交给django的中间件,执行中间件的process_request(process_view)。 - 路由系统进行路由匹配。 - 匹配成功执行视图函数,视图函数进行业务处理(ORM操作数据+模板渲染) - 交给中间件的process_response方法 - wsigref的socket.send,将结果返回给浏览器。 - 断开socket连接。 - 浏览器断开连接。 详细:见django请求生命周期图 5. 什么是wsgi? wsgi,web服务网关接口,他是一套协议。 实现wsgi协议有: - wsgiref - uwsgi 实现wsgi协议的所有的模块本质:socket服务端。 6. django中间件的作用?应用场景? 中间件,可以对所有请求进行批量操作。 应用场景: - 自己玩 - 记录日志 - IP黑名单 - 权限系统中的权限校验 - 解决跨域:编写一个中间件,在中间件中定义一个process_response,添加一个响应头(CORS,跨站资源共享) - 用户登录 - csrf_token验证(django内置功能) 细节: - 5个方法:process_request/process_response + 3 - 执行流程 正常流程: - 所有process_request - 所有process_view - 所有process_response 非正常流程: - django 1.10及以后:平级返回 - django 1.10以前:找到最后的process_response - 写代码时,如果忘记方法名称或方法参数个数,怎么办? - 任意导入一个源码查看,如: # from django.middleware.common import CommonMiddleware MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ] - 执行流程是如何实现的? 将中间件的相关方法添加到对应的 5个列表中,以后循环执行(顺序、倒序) 源码: class BaseHandler(object): def __init__(self): self._request_middleware = None self._view_middleware = None self._template_response_middleware = None self._response_middleware = None self._exception_middleware = None self._middleware_chain = None def load_middleware(self): """ Populate middleware lists from settings.MIDDLEWARE (or the deprecated MIDDLEWARE_CLASSES). Must be called after the environment is fixed (see __call__ in subclasses). """ self._request_middleware = [] self._view_middleware = [] self._template_response_middleware = [] self._response_middleware = [] self._exception_middleware = [] if settings.MIDDLEWARE is None: warnings.warn( "Old-style middleware using settings.MIDDLEWARE_CLASSES is " "deprecated. Update your middleware and use settings.MIDDLEWARE " "instead.", RemovedInDjango20Warning ) handler = convert_exception_to_response(self._legacy_get_response) for middleware_path in settings.MIDDLEWARE_CLASSES: mw_class = import_string(middleware_path) try: mw_instance = mw_class() except MiddlewareNotUsed as exc: if settings.DEBUG: if six.text_type(exc): logger.debug('MiddlewareNotUsed(%r): %s', middleware_path, exc) else: logger.debug('MiddlewareNotUsed: %r', middleware_path) continue if hasattr(mw_instance, 'process_request'): self._request_middleware.append(mw_instance.process_request) if hasattr(mw_instance, 'process_view'): self._view_middleware.append(mw_instance.process_view) if hasattr(mw_instance, 'process_template_response'): self._template_response_middleware.insert(0, mw_instance.process_template_response) if hasattr(mw_instance, 'process_response'): self._response_middleware.insert(0, mw_instance.process_response) if hasattr(mw_instance, 'process_exception'): self._exception_middleware.insert(0, mw_instance.process_exception) else: handler = convert_exception_to_response(self._get_response) for middleware_path in reversed(settings.MIDDLEWARE): middleware = import_string(middleware_path) try: mw_instance = middleware(handler) except MiddlewareNotUsed as exc: if settings.DEBUG: if six.text_type(exc): logger.debug('MiddlewareNotUsed(%r): %s', middleware_path, exc) else: logger.debug('MiddlewareNotUsed: %r', middleware_path) continue if mw_instance is None: raise ImproperlyConfigured( 'Middleware factory %s returned None.' % middleware_path ) if hasattr(mw_instance, 'process_view'): self._view_middleware.insert(0, mw_instance.process_view) if hasattr(mw_instance, 'process_template_response'): self._template_response_middleware.append(mw_instance.process_template_response) if hasattr(mw_instance, 'process_exception'): self._exception_middleware.append(mw_instance.process_exception) handler = convert_exception_to_response(mw_instance) # We only assign to this when initialization is complete as it is used # as a flag for initialization being complete. self._middleware_chain = handler - 根据字符串的形式导入模块 + 根据反射找到模块中的成员 总结: 特点: - 所有请求都要通过中间件 - 5个方法 - 5个方法的执行流程 - 正常 - 不正常(版本区别) 应用场景: - 自己玩: - IP黑名单限制 - 日志 - 工作场景: - 权限控制 - 跨域 - 登录 - CSRF 相关知识点: - 流程实现原理:列表+列表翻转 - 根据字符串的形式导入模块+反射 7. 路由系统 本质:保存url和函数的对应关系。 相关知识点: 示例1: url(r'^index/', views.index), def index(request): return HttpResponse('...') 示例2: url(r'^user/edit/(\d+)/$', views.user_edit), def user_edit(request,nid): return HttpResponse('...') 示例3: url(r'^crm/', include('app01.urls')) from django.conf.urls import url,include from app01 import views urlpatterns = [ url(r'^order/', views.order), url(r'^center/', views.center), ] def order(request): return HttpResponse('...') def center(request): return HttpResponse('...') 示例4:根据name别名反向生成URL urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^index/', views.index,name='index'), url(r'^user/edit/(\d+)/$', views.user_edit,name='user_edit'), url(r'^crm/', include('app01.urls')), ] urlpatterns = [ url(r'^order/', views.order,name='order'), url(r'^center/', views.center,name='center'), ] 反向生成: index_url = reverse('index') user_edit_url = reverse('user_edit',args=('999',)) index_url = reverse('order') index_url = reverse('center') 示例5:根据 namespace + name 别名反向生成URL urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^index/', views.index,name='index'), url(r'^user/edit/(\d+)/$', views.user_edit,name='user_edit'), url(r'^crm/', include('app01.urls',namespace='crm')), ] urlpatterns = [ url(r'^order/', views.order,name='order'), url(r'^center/', views.center,name='center'), ] 视图中反向生成: index_url = reverse('index') user_edit_url = reverse('user_edit',args=('999',)) index_url = reverse('crm:order') index_url = reverse('crm:center') 在模板中反向生成: {% url 'index' %} {% url 'user_edit' 999 %} {% url 'crm:order' %} {% url 'crm:center' %} 补充:公司项目从路由开始看,可能你看到的是这样。 urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^index/', views.index,name='index'), url(r'^user/edit/(\d+)/$', views.user_edit,name='user_edit'), url(r'^crm/', include('app01.urls',namespace='crm')), ] urlpatterns += [ url(r'^xxxx/', views.index), ] 8. 什么是MVC、MTV? MVC, Model View Controller MTV, Model Template View 9. FBV和CBV FBV,写函数进行处理业务逻辑。 CBV,写类进行处理业务逻辑。 本质上FBV和CBV都是一样的,因为url对应都是一个函数。 url(r'^order/', views.order,name='order'), # 1. 对应order函数;2.一旦请求到来,立即执行order函数 url(r'^center/', views.CenterView.as_view(),name='center'), # 1. url对应 views.CenterView.as_view()会返回一个view函数;2. 请求到来之后,立即执行view函数,view由会触发dispatch方法、dispatch会根据method不同根据反射执行get/post/delete...的方法。 推荐: 业务逻辑,FBV(简单)。 restful api,CBV。 10. 现象:两个系统之间进行相互数据传输,李超向讲师机发送POST请求,但讲师机的request.POST中没有获取到数据,可能是因为什么? 1. csrf_token from django.views.decorators.csrf import csrf_exempt,csrf_protect @csrf_exempt def api(request): """ 为李超提供的API接口 :param request: :return: """ print(request.POST) return HttpResponse('...') 实例代码: 李超.py: import requests response = requests.post('http://127.0.0.1:8000/crm/api/',data={'user':'alex','pwd':'dsb'}) print(response.text) Http请求格式: """POST /crm/api/ http\1.1\r\nhost:..\r\nContent-Type:application/x-www-form-urlencoded .....\r\n\r\nuser=alex&pwd=dsb""" django服务端: from django.views.decorators.csrf import csrf_exempt,csrf_protect @csrf_exempt def api(request): """ 为李超提供的API接口 :param request: :return: """ print(request.POST) return HttpResponse('...') 2. request.POST解析时,有限制。 李超.py import requests response = requests.post('http://127.0.0.1:8000/crm/api/',json={'user':'alex','pwd':'dsb'}) print(response.text) Http请求格式: """POST /crm/api/ http\1.1\r\nhost:..\r\nContent-Type:application/json .....\r\n\r\n{'user':'alex','pwd':'dsb'}""" django服务端: @csrf_exempt def api(request): """ 为李超提供的API接口 :param request: :return: """ print(request.body) # 原生的请求体格式,有数据;(自己读取body然后进行解析) print(request.POST) # 将原生的请求体转换成 QueryDict对象,无数据。 return HttpResponse('...') 注意: request.POST 将原生的请求体转换成 QueryDict对象,请求必须满足两个条件才能转换: - Content-Type:application/x-www-form-urlencoded - 数据格式: user=alex&pwd=dbs&xxx=123 如果不满足此条件,django获取请求体时需要自己去request.body中获取值。 总结: django获取请求体 request.body request.POST是将请求体的数据转换成了QueryDict对象。 11. 视图函数的返回值 HttpResponse render 示例1: 视图: def test(request): """ :param request: :return: """ return render(request,'test.html',{'k1':123}) test.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> </head> <body> <div> <h1>{{ k1 }}</h1> <script> alert('{{ k1 }}'); </script> </div> </body> </html> 示例2: 视图: def test(request): """ :param request: :return: """ return render(request,'test.html',{'k1':123}) test.html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta http-equiv="x-ua-compatible" content="IE=edge"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>Title</title> </head> <body> <div> <h1>{{ k1 }}</h1> <script src='/static/commons.js'></script> </div> </body> </html> commons.js alert('{{k1}}') redirect 将要重定向的地址通过响应头Location响应头返回给浏览器。
Django 生命周期涉及知识点一网打尽 第一篇
猜你喜欢
转载自www.cnblogs.com/pupilheart/p/9910859.html
今日推荐
周排行