Http请求的本质:
socket之间进行通信
Django程序:socket服务端
a.服务端监听IP和端口
c.接受请求
请求头之间 分割
请求体之间 分割
请求分为POST请求和GET请求:POST请求有请求头和请求体,GET请求只有请求头
d.服务器响应
响应头和响应体
e.断开连接
浏览器:socket客户端
b.浏览器发送请求
e.断开连接
Cookie:在请求头和响应头中存在
写浏览器cookie:{session_id: '随机字符串' }
用户认证成功后,写入用户信息到服务器session:{ '随机字符串' :{key : value,......}}
每次用户请求都在cookie中携带session_id,服务器根据session_id寻找对应的用户信息
Django的请求生命周期:
Django没有socket
1.wsgiref的socket接受数据
2.数据通过中间件到达路由系统
3.路由系统分发到相应的视图函数
4.视图函数通过ORM到数据库中取得相应的数据,并获得模板将数据进行渲染最后返回中间件,通过wsgi返回给用户
FBV
urlpatterns = [ url(r'^admin/', admin.site.urls), url(r'^index.html$', views.index), #FBV ] def index(request): return HttpResponse('OK') #FBV
CBV
urlpatterns = [ url(r'^admin/', admin.site.urls), # url(r'^index.html$', views.index), #FBV url(r'^index.html$', views.IndexView.as_view()), #CBV url(r'^login.html$', views.LoginView.as_view()), #CBV ] class AuthView(View): def dispatch(self, request, *args, **kwargs): if not request.session['user_login']: return redirect('/login.html') res=super(AuthView, self).dispatch(request,*args,**kwargs) return res class LoginView(View): def get(self,request): return (request,"login.html") def post(self,request): user=request.POST.get('name') pwd=request.POST.get('pwd') if user == 'xiaobai' and pwd == 'youzi': request.session['user_login']='xiaobai' return redirect('/index.html') return render(request,"login.html") class IndexView(AuthView): def get(self,request,*args,**kwargs): return render(request,'index.html') def post(self,request,*args,**kwargs): return HttpResponse('youzi')
CBV的装饰器
1.加在get和post方法上
def test(func): def inner(*args,**kwargs): return func(*args,**kwargs) return inner class LoginView(View): def dispatch(self, request, *args, **kwargs): return super(LoginView,self).dispatch(request, *args, **kwargs) @method_decorator(test) def get(self,request): return render(request,'login.html') @method_decorator(test) def post(self,request): # request.GET # request.POST # 请求头中的:content-type # request.body user = request.POST.get('user') pwd = request.POST.get('pwd') if user == 'alex' and pwd == "alex3714": # 生成随机字符串 # 写浏览器cookie: session_id: 随机字符串 # 写到服务端session: # { # "随机字符串": {'user_info':'alex} # } request.session['user_info'] = "alex" return redirect('/index.html') return render(request, 'login.html')
2.加在dispatch上
class LoginView(View): @method_decorator(test) def dispatch(self, request, *args, **kwargs): return super(LoginView,self).dispatch(request, *args, **kwargs) def get(self,request): return render(request,'login.html') def post(self,request): # request.GET # request.POST # 请求头中的:content-type # request.body user = request.POST.get('user') pwd = request.POST.get('pwd') if user == 'alex' and pwd == "alex3714": # 生成随机字符串 # 写浏览器cookie: session_id: 随机字符串 # 写到服务端session: # { # "随机字符串": {'user_info':'alex} # } request.session['user_info'] = "alex" return redirect('/index.html') return render(request, 'login.html')
3.加在类上
@method_decorator(test,name='get') class LoginView(View): def dispatch(self, request, *args, **kwargs): return super(LoginView,self).dispatch(request, *args, **kwargs) def get(self,request): return render(request,'login.html') def post(self,request): # request.GET # request.POST # 请求头中的:content-type # request.body user = request.POST.get('user') pwd = request.POST.get('pwd') if user == 'alex' and pwd == "alex3714": # 生成随机字符串 # 写浏览器cookie: session_id: 随机字符串 # 写到服务端session: # { # "随机字符串": {'user_info':'alex} # } request.session['user_info'] = "alex" return redirect('/index.html') return render(request, 'login.html')
4.特殊csrf,只能加在dispatch上
全局django.middleware.csrf.CsrfViewMiddleware;下面代码为局部伪造跨站请求
from django.views.decorators.csrf import csrf_exempt,csrf_protect class LoginView(View): @method_decorator(csrf_exempt) def dispatch(self, request, *args, **kwargs): return super(LoginView,self).dispatch(request, *args, **kwargs) def get(self,request): return render(request,'login.html') def post(self,request): # request.GET # request.POST # 请求头中的:content-type # request.body user = request.POST.get('user') pwd = request.POST.get('pwd') if user == 'alex' and pwd == "alex3714": # 生成随机字符串 # 写浏览器cookie: session_id: 随机字符串 # 写到服务端session: # { # "随机字符串": {'user_info':'alex} # } request.session['user_info'] = "alex" return redirect('/index.html') return render(request, 'login.html')
中间件
from django.shortcuts import HttpResponse,redirect class MiddlewareMixin(object): def __init__(self, get_response=None): self.get_response = get_response super(MiddlewareMixin, self).__init__() def __call__(self, request): response = None if hasattr(self, 'process_request'): response = self.process_request(request) if not response: response = self.get_response(request) if hasattr(self, 'process_response'): response = self.process_response(request, response) return response class M1(MiddlewareMixin): def process_request(self,request): print('m1.process_request') def process_view(self,request, view_func, view_func_args, view_func_kwargs): print('m1.process_view') def process_exception(self,request,exception): print('m1.process_exception') def process_response(self,request,response): print('m1.process_response') return response def process_template_response(self,request,response): print('m1.process_template_response') return response class M2(MiddlewareMixin): def process_request(self, request): print('m2.process_request') def process_view(self, request, view_func, view_func_args, view_func_kwargs): print('M2.process_view') def process_exception(self,request,exception): print('m2.process_exception') return HttpResponse('开发的程序员已经被打死') def process_response(self, request, response): print('m2.process_response') return response def process_template_response(self,request,response): print('m2.process_template_response') return response
process_request和process_response
请求信息从上而下执行各个中间件的process_request,进行路由匹配执行相应的视图函数,返回值通过中间件自下而上执行process_response;如果编写的process_request有return 返回值时,会执行平行的process_response返回给用户
process_view
中间价中存在process_view时:
中间价从上而下执行process_request,全部执行完成之后会进行路由匹配,从上而下执行中间件的process_view最后执行匹配到的视图函数,返回中间件执行process_response;如果process_view有return返回值时,不会执行匹配到的视图函数,而是从下而上执行中间件的process_response
process_exception
process_exception 默认不执行,在视图函数出错时执行,有return返回值;请求发来后,中间件从上而下执行process_request,进行路由匹配,继续按照从上而下的顺序执行process_view,出错后从下而上执行捕获到的process_exception然后按照从下而下执行process_response
process_template_response
process_template_response 默认不执行,返回的对象如果有render方法时会运行,有返回值
return response