用于必须登录后才能访问否个视图。

url.py

  1. from django.conf.urls import url,include
  2. from django.contrib import admin
  3. from . import views
  4. urlpatterns = [
  5. url(r\'^login/$\', views.LoginView.as_view()),
  6. url(r\'^order/$\', views.OrderView.as_view()),
  7. url(r\'^user/$\', views.UserView.as_view()),
  8. ]

views.py

  1. import uuid
  2. from django.shortcuts import render
  3. from django.views import View
  4. from django.views.decorators.csrf import csrf_exempt
  5. from django.utils.decorators import method_decorator
  6. from rest_framework.versioning import URLPathVersioning
  7. from rest_framework.views import APIView
  8. from rest_framework.response import Response
  9. from . import models
  10. class LoginView(APIView):
  11. def post(self,request,*args,**kwargs):
  12. user_object = models.UserInfo.objects.filter(**request.data).first()
  13. if not user_object:
  14. return Response(\'登录失败\')
  15. random_string = str(uuid.uuid4()) # 产生随机字符串
  16. user_object.token = random_string # 保存在数据库
  17. user_object.save()
  18. return Response(random_string)
  19. class MyAuthentication:
  20. def authenticate(self, request):
  21. # 重写这个方法
  22. """
  23. Authenticate the request and return a two-tuple of (user, token).
  24. """
  25. token = request.query_params.get(\'token\')
  26. # 获取请求携带的token,然后获取用户对象
  27. user_object = models.UserInfo.objects.filter(token=token).first()
  28. if user_object:
  29. return (user_object,token)
  30. return (None,None)
  31. class OrderView(APIView):
  32. authentication_classes = [MyAuthentication, ]
  33. # 需要登录认证的视图,设置类列表
  34. def get(self,request,*args,**kwargs):
  35. print(request.user) # 获取用户对象
  36. print(request.auth) # 获取token
  37. return Response(\'order\')
  38. class UserView(APIView):
  39. authentication_classes = [MyAuthentication,]
  40. def get(self,request,*args,**kwargs):
  41. print(request.user)
  42. print(request.auth)
  43. return Response(\'user\')
  1. class APIView(View):
  2. authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES
  3. def dispatch(self, request, *args, **kwargs):
  4. """
  5. `.dispatch()` is pretty much the same as Django\'s regular dispatch,
  6. but with extra hooks for startup, finalize, and exception handling.
  7. """
  8. # ###################### 第一步 ###########################
  9. """
  10. request,是django的request,它的内部有:request.GET/request.POST/request.method
  11. args,kwargs是在路由中匹配到的参数,如:
  12. url(r\'^order/(\d+)/(?P<version>\w+)/$\', views.OrderView.as_view()),
  13. http://www.xxx.com/order/1/v2/
  14. """
  15. self.args = args
  16. self.kwargs = kwargs
  17. """
  18. request = 生成了一个新的request对象,此对象的内部封装了一些值。
  19. request = Request(request)
  20. - 内部封装了 _request = 老的request
  21. - 内部封装了 authenticators = [MyAuthentication(), ] 对象类列表
  22. """
  23. request = self.initialize_request(request, *args, **kwargs)
  24. self.request = request
  25. def initialize_request(self, request, *args, **kwargs):
  26. """
  27. Returns the initial request object.
  28. """
  29. parser_context = self.get_parser_context(request)
  30. return Request(
  31. request,
  32. parsers=self.get_parsers(),
  33. authenticators=self.get_authenticators(), # 认证[MyAuthentication(),]
  34. negotiator=self.get_content_negotiator(),
  35. parser_context=parser_context
  36. )
  37. def get_authenticators(self):
  38. """
  39. Instantiates and returns the list of authenticators that this view can use.
  40. """
  41. return [ auth() for auth in self.authentication_classes ]
  1. def perform_authentication(self, request):
  2. request.user

会执行Request中def user()

  1. def user(self):
  2. self._authenticate()
  3. def _authenticate(self):
  4. for authenticator in self.authenticators:
  5. user_auth_tuple = authenticator.authenticate(self) # 循环上面获取到的认证对象类列表,执行自定制的auhenticate()方法
  1. 1. 当前请求到来时,执行APIview dispatch方法,request = self.initialize_request()先进行新的request封装,其中封装了老request、认证类对象列表等。
  2. 2. 然后执行 initial方法,先进行分页、再进行认证执行 perform_authentication() --- request.user
  3. 3.执行Requestdef user(), user中循环认证类对象列表,执行每个对象的 def authenticate()(重写的方法),有三种返回方式:
  4. - 元组:认证通过
  5. - None:进行下个类的认证
  6. - 主动抛出异常:认证失败
  7. 下面两种方式可以触发第三步的认证:
  8. request.user 能够获取当前登录用户对象
  9. request.auth 获取toke

版权声明:本文为yzm1017原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://www.cnblogs.com/yzm1017/p/11953866.html