–
时间:2019.2.18
视频:https://www.bilibili.com/video/av28871471/?p=1
博客:http://www.cnblogs.com/wupeiqi/articles/7805382.html
P1day128-01 今日内容概要
P2day128-02 内容回顾
P3day128-03 django视图之CBV基本使用
P4day128-04 django视图之CBV源码流程
P5day128-05 django视图之面试题和csrf补充
P6day128-06 django视图之CBV解决csrf认证
P7day128-07 以上内容梳理
P8day128-08 基于django实现restful api
P9day128-09 restful 协议
P10day128-10 面试题之谈谈你对restful协议的认识
P11day128-11 rest framework框架之认证使用和源码执行流程
P12day128-12 rest framework框架之认证内容梳理
P13day128-13 今日作业
P1day128-01 今日内容概要 面试过程讲解 用drf框架可以更省事 今日概要: 1、restful规范 2、drf框架 P2day128-02 内容回顾 内容回顾: 1、开发模式: - 普通开发模式(前后端放在一起) - 前后端分离 前后端交互都是通过ajax交互 2、前后端分离优点 - 当有pc和app两个前端的时候,后端只用维护一套代码,只修改对应的前端就可以 - 后端逻辑更加清晰 3、简单的api示例 创建一个django项目 下面是url.py里面的文件 from django.conf.urls import url # from django.contrib import admin from app01 import views urlpatterns = [ # url(r'^admin/', admin.site.urls), url(r'users', users) ] 下面是app01.views里面的文件 from django.shortcuts import render, HttpResponse import json def users(request): user_list = ['andy', 'bob'] return HttpResponse(json.dumps(user_list)) 在浏览器里面输入:http://127.0.0.1:8000/users 就可以实现简单的api接口 4、django FBV,CBV function base view class base view 下面是cbv示例,当用户使用get方法的时候,得到get,使用post方法的时候,得到post,所有的方法都在.as_view里面 比fbv方便,已经写好了各种方法 创建一个django项目 下面是url.py里面的文件 from django.conf.urls import url # from django.contrib import admin from app01 import views urlpatterns = [ # url(r'^admin/', admin.site.urls), url(r'users', views.users), url(r'student', views.StudentView.as_view()) ] 下面是app01.views里面的文件 from django.views import View class StudentView(View): def get(self, request, *args, **kwargs): return HttpResponse('get') def post(self, request, *args, **kwargs): return HttpResponse('post') def put(self, request, *args, **kwargs): return HttpResponse('post') def delete(self, request, *args, **kwargs): return HttpResponse('post') 当使用postman进行post方式测试的时候,需要先将csrf中间件注释,不然错误 5、列表生成式 下面的程序作用是分别根据两个类实例化两个对象,然后放到v list里面,下面是简写。v就是一个对象列表 class Foo: pass class Bar: pass v = [] for i in [Foo, Bar]: obj = i() v.append(obj) v = [item() for item in [Foo, Bar]] 6、面向对象:封装,继承,多态 - 封装 类可以对同一类的方法封装到一个类。就是最常见的一个类下面多个方法 类可以将数据封装到对象中。可以通过__init__方法在类生成对象的时候将数据传入到对象中 下面是一个封装示例,结果是True,里面调用了很多层,把对象当做数据传入了 class Request(object): def __init__(self, obj): self.obj = obj @property def user(self): return self.obj.authticate() class Auth(object): def __init__(self, name, age): self.name = name self.age = age def authticate(self): return True class APIView(object): def dispatch(self): self.f2() def f2(self): a = Auth('alex', 18) req = Request(a) print(req.user) obj = APIView() obj.dispatch() P3day128-03 django视图之CBV基本使用 根据不同的请求方法调用不同的函数,是基于反射来处理的 根据url执行as_view()方法,as_view()方法是View类里面的一个方法 url(r'student', views.StudentView.as_view()) views.StudentView.as_view()执行完成后会返回一个函数view,主要就是看这个view class View(object): def as_view(cls, **initkwargs): def view(request, *args, **kwargs): #self = StudentView(),cls是当前请求的类。类加括号,实例化对象 self = cls(**initkwargs) if hasattr(self, 'get') and not hasattr(self, 'head'): self.head = self.get self.request = request self.args = args self.kwargs = kwargs return self.dispatch(request, *args, **kwargs) view.view_class = cls view.view_initkwargs = initkwargs # take name and docstring from class update_wrapper(view, cls, updated=()) # and possible attributes set by decorators # like csrf_exempt from dispatch update_wrapper(view, cls.dispatch, assigned=()) return view 看self.dispatch的执行过程,根据反射来判断不同的方法 def dispatch(self, request, *args, **kwargs): # Try to dispatch to the right method; if a method doesn't exist, # defer to the error handler. Also defer to the error handler if the # request method isn't on the approved list. if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed return handler(request, *args, **kwargs) 用户请求进来,请求dispatch,不管是什么请求进来,什么方法,都执行 如果在用户自定义的view里面定义dispatch方法,重载,使用子类同名方法。 下面的方式,不管什么方法请求,返回的都是hello class StudentView(View): def dispatch(self, request, *args, **kwargs): return HttpResponse('hello') 下面是自定义的根据反射执行不同的方法,这里返回的要是函数 class StudentView(View): def dispatch(self, request, *args, **kwargs): func = getattr(self, request.method.lower(), *args, **kwargs) ret = func(request, *args, **kwargs) return ret def get(self, request, *args, **kwargs): return HttpResponse('get') def post(self, request, *args, **kwargs): return HttpResponse('post') def put(self, request, *args, **kwargs): return HttpResponse('post') def delete(self, request, *args, **kwargs): return HttpResponse('post') django已经给我们做好了上面的步骤,可以直接用 可以自己在所有请求执行之前执行某些操作,比如权限等,类似于下面的print函数。也可以使用装饰器实现 class StudentView(View): def dispatch(self, request, *args, **kwargs): print('before') ret = super(StudentView,self).dispatch(request, *args, **kwargs) print('after') return ret def get(self, request, *args, **kwargs): return HttpResponse('get') def post(self, request, *args, **kwargs): return HttpResponse('post') def put(self, request, *args, **kwargs): return HttpResponse('post') def delete(self, request, *args, **kwargs): return HttpResponse('post') 程序执行过程:url - view方法 - dispatch方法 具体查看图片
–
P4day128-04 django视图之CBV源码流程 多个类公用的功能,可以根据继承来实现,MyBaseView里面的self指的是StudentView这个类,在当前类中找不到dispatch方法的时候,会去其他的父类View中查找 class MyBaseView(object): def dispatch(self, request, *args, **kwargs): print('before') ret = super(MyBaseView,self).dispatch(request, *args, **kwargs) print('after') return ret class StudentView(MyBaseView, View): def get(self, request, *args, **kwargs): return HttpResponse('get') def post(self, request, *args, **kwargs): return HttpResponse('post') def put(self, request, *args, **kwargs): return HttpResponse('post') def delete(self, request, *args, **kwargs): return HttpResponse('post') P5day128-05 django视图之面试题和csrf补充 django有5类中间件 - process_request - process_view - process_response - process_exception - process_render_template 用中间件都做过什么 - 权限 - 用户登录验证 当把中间件中的csrf打开后,csrf全局生效 当想让students类中的某个方法不使用csrf功能 from django.views.decorators.csrf import csrf_exempt @csrf_exempt def users(request): user_list = ['andy', 'bob'] return HttpResponse(json.dumps(user_list)) 当把中间件中的csrf关闭后,csrf全局失效 当想让students类中的某个方法使用csrf功能 from django.views.decorators.csrf import csrf_protect @csrf_protect def users(request): user_list = ['andy', 'bob'] return HttpResponse(json.dumps(user_list)) P6day128-06 django视图之CBV解决csrf认证 cbv实现上面的功能,需要在dispatch方法上面加才可以,加到单独的方法上面无效 from django.views import View from django.utils.decorators import method_decorator class StudentView(View): @method_decorator(csrf_exempt) def dispatch(self, request, *args, **kwargs): ret = super(StudentView,self).dispatch(request, *args, **kwargs) return ret def get(self, request, *args, **kwargs): return HttpResponse('get') def post(self, request, *args, **kwargs): return HttpResponse('post') def put(self, request, *args, **kwargs): return HttpResponse('post') def delete(self, request, *args, **kwargs): return HttpResponse('post') P7day128-07 以上内容梳理 P8day128-08 基于django实现restful api 对于普通的路径,如果不通过方法来进行区分,要实现增删改查功能,要四个路径才可以 举了一个例子 P9day128-09 restful 协议 http://www.cnblogs.com/wupeiqi/articles/7805382.html 具体查看博客内容 一般http的状态码有限,表示的内容有限,所以更多的使用自定义的code返回给用户来显示 P10day128-10 面试题之谈谈你对restful协议的认识 跨域怎么解决 P11day128-11 rest framework框架之认证使用和源码执行流程 drf:django rest framwork 安装:pip3 install djangorestframework a、cbv 下面是使用drf的简单示例 from django.shortcuts import HttpResponse from rest_framework.views import APIView from rest_framework.authentication import BaseAuthentication class StudentView(APIView): authentication_classes = [BaseAuthentication,] def get(self, request, *args, **kwargs): #这个是drf的dispatch方法,而不是django自带的dispatch方法 #drf的as_view方法里面调用view = super(APIView, cls).as_view(**initkwargs)父类的as_view方法, #父类的as_view里面调用了dispatch方法,但是drf里面也有dispatch方法,实际调用drf里面的dispatch方法 #从这里点进去可以查看dispatch方法的具体执行过程, self.dispatch() return HttpResponse('get') def post(self, request, *args, **kwargs): return HttpResponse('post') def put(self, request, *args, **kwargs): return HttpResponse('post') def delete(self, request, *args, **kwargs): return HttpResponse('post') #具体函数分析 def dispatch(self, request, *args, **kwargs): """ `.dispatch()` is pretty much the same as Django's regular dispatch, but with extra hooks for startup, finalize, and exception handling. """ self.args = args self.kwargs = kwargs #对原生的request进行加工,添加一些额外的东西,更多了 request = self.initialize_request(request, *args, **kwargs) self.request = request self.headers = self.default_response_headers # deprecate? #下面的和django自带的功能差不多 try: #下面的方法进行初始化操作,包括权限,认证,限速等操作 self.initial(request, *args, **kwargs) # Get the appropriate handler method if request.method.lower() in self.http_method_names: handler = getattr(self, request.method.lower(), self.http_method_not_allowed) else: handler = self.http_method_not_allowed response = handler(request, *args, **kwargs) except Exception as exc: response = self.handle_exception(exc) self.response = self.finalize_response(request, response, *args, **kwargs) return self.response 往里找initialize_request函数增加了额外的属性 return Request( request, parsers=self.get_parsers(), authenticators=self.get_authenticators(), 这个是添加了认证类型的变量 negotiator=self.get_content_negotiator(), parser_context=parser_context ) 往里找get_authenticators函数功能 def get_authenticators(self): #返回实例化后的对象列表 return [auth() for auth in self.authentication_classes] 往里找authentication_classes这个类为设置的用户在配置文件里面设置的,如果用户在类里面自定义了,则使用用户自定义的 authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES 在用户视图中添加自定义变量,现在的request里面封装了两个,一个是原生的request,一个是[BaseAuthentication,] 查看具体的Request类,看这个类进行实例化的时候进行了什么处理 return Request( request, parsers=self.get_parsers(), authenticators=self.get_authenticators(), negotiator=self.get_content_negotiator(), parser_context=parser_context ) 从下面可以看到,原生的request被封装为_request对象,子类中如果想要调用原生的request,使用_request class Request(object): def __init__(self, request, parsers=None, authenticators=None, negotiator=None, parser_context=None): self._request = request self.parsers = parsers or () self.authenticators = authenticators or () 查看初始化操作做了哪些事情 def initial(self, request, *args, **kwargs): self.format_kwarg = self.get_format_suffix(**kwargs) # Perform content negotiation and store the accepted info on the request neg = self.perform_content_negotiation(request) request.accepted_renderer, request.accepted_media_type = neg #下面是版本控制 # Determine the API version, if versioning is in use. version, scheme = self.determine_version(request, *args, **kwargs) request.version, request.versioning_scheme = version, scheme # Ensure that the incoming request is permitted #下面认证的方法实际调用了user属性 self.perform_authentication(request) #下面是检查权限的 self.check_permissions(request) #下面是检查访问频率的 self.check_throttles(request) #user属性位置:request.py的189行 @property def user(self): """ Returns the user associated with the current request, as authenticated by the authentication classes provided to the request. """ if not hasattr(self, '_user'): self._authenticate() return self._user 继续查看_authenticate函数,authenticators为BaseAuthentication对象,然后执行authenticate方法。验证是否已经登录。如果已经登录,返回元组。如果没有登录,抛异常 def _authenticate(self): """ Attempt to authenticate the request using each authentication instance in turn. """ for authenticator in self.authenticators: try: user_auth_tuple = authenticator.authenticate(self) except exceptions.APIException: self._not_authenticated() raise if user_auth_tuple is not None: self._authenticator = authenticator self.user, self.auth = user_auth_tuple return self._not_authenticated() 可以自己定义类和方法来重写上面的方法 原理:只要是将类放到authentication_classes中,根据上面的执行流程 就会依次执行这个类里面的authenticator.authenticate(self)方法 这个类我们可以自己定义,然后到authenticator.authenticate(self)的时候,执行自己的方法 访问:http://127.0.0.1:8000/students会报没有权限 访问:http://127.0.0.1:8000/students?token=123带上token才能正常访问 也就是说只要是需要带认证的都可以类似于这个自己定义 认证通过后,返回的元组为用户信息,request.user from django.shortcuts import HttpResponse from rest_framework.views import APIView from rest_framework.authentication import BaseAuthentication from rest_framework import exceptions class MyAuthentication(object): def authenticate(self, request): token = request._request.GET.get('token') if not token: raise exceptions.AuthenticationFailed('用户认证失败') return ('alex', None) def authenticate_header(self, vl): pass class StudentView(APIView): authentication_classes = [MyAuthentication,] def get(self, request, *args, **kwargs): return HttpResponse('get') def post(self, request, *args, **kwargs): return HttpResponse('post') P12day128-12 rest framework框架之认证内容梳理 总结 P13day128-13 今日作业 需要看源码流程,非常重要
–
–
评论前必须登录!
注册