看Django和DRF的源码+用户认证

怎样看Django和DRF的源码

CBV原理

class OrderView(View):
    def get(self, request, *args, **kwargs):
        ret = {
    
    
            'code': 1000,
            'msg': 'xxx'
        }

        return HttpResponse(json.dumps(ret), status=201)

    def post(self, request, *args, **kwargs):
        return HttpResponse('创建订单')

    def put(self, request, *args, **kwargs):
        return HttpResponse('更新订单')

    def delete(self, request, *args, **kwargs):
        return HttpResponse('删除订单')
  • 我们自定义一个OrderView类,继承于View

  • path('order/',views.OrderView.as_view()),
    
  • url中是调用的OrderViewas_view()方法,但是我们并没有定义,说明这个方法是继承于View

  • 于是找到View中的as_view()

image-20200830093221565

  • 其中cls指的就是我们自定义的OrderView,而self则是将其实例化后的对象

  • 接下来跳转至dispatch方法

    image-20200830093802948

  • 可以知道`如果在Django项目中使用CBV的模式,实际上调用了getattr的方式来执行获取类中的请求方法对应的函数

  • 当然也可以自定义dispatch方法来实现自己的操作

DRF的APIView源码+用户认证

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, val):
        pass

class DogView(APIView):
    # 进行用户认证
    authentication_classes = [Myauthentication, ]
    def get(self, request, *args, **kwargs):
        print(request)
        # 此request和原生的request不同
        # 是DRF的dispatch加工后的request
        print(request.user)
        # 即Myauthentication中的authenticate返回的元组
        self.dispatch
        ret = {
    
    
            'code': 1000,
            'msg': 'xxx'
        }
        return HttpResponse(json.dumps(ret), status=201)

    def post(self, request, *args, **kwargs):
        return HttpResponse('创建Dog')

    def put(self, request, *args, **kwargs):
        return HttpResponse('更新Dog')

    def delete(self, request, *args, **kwargs):
        return HttpResponse('删除Dog')

  • 同理,根据urls文件可知,先去找as_view()方法,

  • 自定义的DogView没有,那么去找它的父类,即APIViewas_view()

    扫描二维码关注公众号,回复: 16248204 查看本文章
  • image-20200830094832187

  • 可见它是调用了Viewas_view()方法,而通过上面的CBV分析,最终是调用selfdispatch方法

  • 然而,需要注意,此例self,指的是我们自定义的DogView,因此想要寻找dispatch,需要从DogView一层一层的找

  • APIView中是有dispatch方法的,故而转到源码

    image-20200830095817777

  • 原生的requestintialize_request加工,跳转至源码

  • image-20200830100806104

  • 其中增加了一项authenticators,调用的是self.get_authenticators,同理,这个方法,也需要从DogView开始找,自己没有向父类找

  • image-20200830101147658

  • self.authentication_classes的类列表实例化为对象,继续跳转

  • image-20200830101311037

  • 可以在DogView中自定义一个authentication_classes,就可以将默认的覆盖

  • 回到APIView中的dispatch,找到intial跳转,(传入的参数是加工后的request)

  • image-20200830101947804

  • 继续跳转

    image-20200830102051095

  • 找到加工后的request(从intialize_request返回值处跳转)

  • 左侧先设置展开

image-20200830102345439

  • image-20200830102427054

  • 找到user

image-20200830102614040

  • 继续跳转

image-20200830102720347

  • 其中每一个authenticator都有一个authenticate方法,所以我们在自定义的Myauthentication中也要写一个authenticate

  • 此外还需要一个authenticate_header方法
    74)]

  • 其中每一个authenticator都有一个authenticate方法,所以我们在自定义的Myauthentication中也要写一个authenticate

  • 此外还需要一个authenticate_header方法

  • 这样实现了基础的用户认证(此时url中token可以随便写)

猜你喜欢

转载自blog.csdn.net/jinniulema/article/details/119103523