zoukankan      html  css  js  c++  java
  • restframework详细

    1.写视图的方法

    1.1第一种:原始APIView

    url(r'^login/$',account.LoginView.as_view()),
    
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from rest_framework_jwt.settings import api_settings
    from rest_framework.throttling import AnonRateThrottle
    from api import models
    
    
    class LoginView(APIView):
        authentication_classes = []
        def post(self,request,*args,**kwargs):
            # 1.根据用户名和密码检测用户是否可以登录
            user = models.UserInfo.objects.filter(username=request.data.get('username'),password=request.data.get('password')).first()
            if not user:
                return Response({'code':10001,'error':'用户名或密码错误'})
    
            # 2. 根据user对象生成payload(中间值的数据)
            jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER
            payload = jwt_payload_handler(user)
    
            # 3. 构造前面数据,base64加密;中间数据base64加密;前两段拼接然后做hs256加密(加盐),再做base64加密。生成token
            jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER
            token = jwt_encode_handler(payload)
            return Response({'code': 10000, 'data': token})
    

    1.2第二种:ListApiView等

    url(r'^article/$',article.ArticleView.as_view()),
    url(r'^article/(?P<pk>d+)/$',article.ArticleDetailView.as_view()),
    
    from rest_framework.throttling import AnonRateThrottle
    from rest_framework.response import Response
    from rest_framework.generics import ListAPIView,RetrieveAPIView
    from api import models
    from api.serializer.article import ArticleSerializer,ArticleDetailSerializer
    
    class ArticleView(ListAPIView):
        authentication_classes = []
        # throttle_classes = [AnonRateThrottle,]
    
        queryset = models.Article.objects.all()
        serializer_class = ArticleSerializer
    
    class ArticleDetailView(RetrieveAPIView):
        authentication_classes = []
        queryset = models.Article.objects.all()
        serializer_class = ArticleDetailSerializer
    

    1.3第三种:

    url(r'^article/$',article.ArticleView.as_view({"get":'list','post':'create'})),
        url(r'^article/(?P<pk>d+)/$',article.ArticleView.as_view({'get':'retrieve','put':'update','patch':'partial_update','delete':'destroy'}))
    
    from rest_framework.viewsets import GenericViewSet
    from rest_framework.mixins import ListModelMixin,RetrieveModelMixin,CreateModelMixin,UpdateModelMixin,DestroyModelMixin
    from api.serializer.article import ArticleSerializer,ArticleDetailSerializer
    
    class ArticleView(GenericViewSet,ListModelMixin,RetrieveModelMixin,CreateModelMixin,UpdateModelMixin,DestroyModelMixin):
        authentication_classes = []
        throttle_classes = [AnonRateThrottle,]
    
        queryset = models.Article.objects.all()
        serializer_class = None
    
        def get_serializer_class(self):
            pk = self.kwargs.get('pk')
            if pk:
                return ArticleDetailSerializer
            return ArticleSerializer
    

    2.drf 相关知识点梳理

    2.1装饰器

    def outer(func):
        def inner(*args,**kwargs):
            return func(*args,**kwargs)
        return inner
    
    @outer
    def index(a1):
        pass
    
    index()
    
    def outer(func):
        def inner(*args,**kwargs):
            return func(*args,**kwargs)
        return inner
    
    def index(a1):
        pass
    
    index = outer(index)
    
    index()
    

    2.2django中可以免除csrftoken认证

    from django.views.decorators.csrf import csrf_exempt
    from django.shortcuts import HttpResponse
    
    @csrf_exempt
    def index(request):
        return HttpResponse('...')
    
    # index = csrf_exempt(index)
    
    urlpatterns = [
        url(r'^index/$',index),
    ]
    
    urlpatterns = [
        url(r'^login/$',account.LoginView.as_view()),
    ]
    
    class APIView(View):
        @classmethod
        def as_view(cls, **initkwargs):
            view = super().as_view(**initkwargs)
            view.cls = cls
            view.initkwargs = initkwargs
    
            # Note: session based authentication is explicitly CSRF validated,
            # all other authentication is CSRF exempt.
            return csrf_exempt(view)
    

    2.3面向对象中基于继承+异常处理来做的约束

    class BaseVersioning:
        def determine_version(self, request, *args, **kwargs):
            raise NotImplementedError("must be implemented")
            
    class URLPathVersioning(BaseVersioning):
    	def determine_version(self, request, *args, **kwargs):
            version = kwargs.get(self.version_param, self.default_version)
            if version is None:
                version = self.default_version
    
            if not self.is_allowed_version(version):
                raise exceptions.NotFound(self.invalid_version_message)
            return version
    

    2.4面向对象封装

    class Foo(object):
    	def __init__(self,name,age):
    		self.name = name
    		self.age = age 
    		
    obj = Foo('汪洋',18)
    
    class APIView(View):
        def dispatch(self, request, *args, **kwargs):
    
            self.args = args
            self.kwargs = kwargs
            request = self.initialize_request(request, *args, **kwargs)
            self.request = request
    		...
            
    	def initialize_request(self, request, *args, **kwargs):
            """
            Returns the initial request object.
            """
            parser_context = self.get_parser_context(request)
    
            return Request( # 给request再封装一层
                request,
                parsers=self.get_parsers(),
                authenticators=self.get_authenticators(), # [MyAuthentication(),]
                negotiator=self.get_content_negotiator(),
                parser_context=parser_context
            )
    

    2.5面向对象继承

    class View(object):
       	pass
    
    class APIView(View):
        def dispatch(self):
            method = getattr(self,'get')
            method()
    
    class GenericAPIView(APIView):
        serilizer_class = None
        
        def get_seriliser_class(self):
            return self.serilizer_class
    
    class ListModelMixin(object):
        def get(self):
            ser_class = self.get_seriliser_class()
            print(ser_class)
    
    class ListAPIView(ListModelMixin,GenericAPIView):
        pass
    
    class UserInfoView(ListAPIView):
        pass
    
    
    view = UserInfoView()
    view.dispatch()
    
    class View(object):
       	pass
    
    class APIView(View):
        def dispatch(self):
            method = getattr(self,'get')
            method()
    
    class GenericAPIView(APIView):
        serilizer_class = None
        
        def get_seriliser_class(self):
            return self.serilizer_class
    
    class ListModelMixin(object):
        def get(self):
            ser_class = self.get_seriliser_class()
            print(ser_class)
    
    class ListAPIView(ListModelMixin,GenericAPIView):
        pass
    
    class UserInfoView(ListAPIView):
        serilizer_class = "汪洋"
    
    
    view = UserInfoView()
    view.dispatch()
    
    class View(object):
       	pass
    
    class APIView(View):
        def dispatch(self):
            method = getattr(self,'get')
            method()
    
    class GenericAPIView(APIView):
        serilizer_class = None
        
        def get_seriliser_class(self):
            return self.serilizer_class
    
    class ListModelMixin(object):
        def get(self):
            ser_class = self.get_seriliser_class()
            print(ser_class)
    
    class ListAPIView(ListModelMixin,GenericAPIView):
        pass
    
    class UserInfoView(ListAPIView):
        
        def get_seriliser_class(self):
            return "咩咩"
    
    view = UserInfoView()
    view.dispatch()
    

    2.6反射

    class View(object):
    	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)
    

    2.7发送ajax请求

    $.ajax({
    	url:'地址',
    	type:'GET',
    	data:{...},
    	success:function(arg){
    		console.log(arg);
    	}
    })
    
    • 简单请求,发送一次请求。
    • 复杂请求,先options请求做预检,然后再发送真正请求
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
        <h1>常鑫的网站</h1>
        <p>
            <input type="button" value="点我" onclick="sendMsg()">
        </p>
        <p>
            <input type="button" value="点他" onclick="sendRemoteMsg()">
        </p>
    
      
        <script src="https://cdn.bootcss.com/jquery/3.4.1/jquery.min.js"></script>
        <script>
            function sendMsg() {
                $.ajax({
                    url:'/msg/',
                    type:'GET',
                    success:function (arg) {
                        console.log(arg);
                    }
                })
            }
            function sendRemoteMsg() {
                $.ajax({
                    url:'http://127.0.0.1:8002/json/',
                    type:'GET',
                    success:function (arg) {
                        console.log(arg);
                    }
                })
    
            }
        </script>
    </body>
    </html>
    
    

    2.8如何解决ajax+跨域?

    CORS,跨站资源共享,本质:设置响应头。
    

    2.9常见的Http请求方法

    get
    post
    put
    patch
    delete
    options
    

    2.10http请求中Content-type请起头

    情况一:
        content-type:x-www-form-urlencode
        name=alex&age=19&xx=10
    	
    	request.POST和request.body中均有值。
    	
    情况二:
    	content-type:application/json
        {"name":"ALex","Age":19}
        
        request.POST没值
        request.body有值。
    

    2.11django中F查询

    2.12django中获取空Queryset

    models.User.object.all().none()
    

    2.13基于django的fbv和cbv都能实现遵循restful规范的接口

    def user(request):
        if request.metho == 'GET':
            pass
        
        
    class UserView(View):
        def get()...
        
        def post...
    

    2.14基于django rest framework框架实现restful api的开发。

    - 免除csrf认证
    - 视图(APIView、ListAPIView、ListModelMinx)
    - 版本
    - 认证
    - 权限
    - 节流
    - 解析器
    - 筛选器
    - 分页
    - 序列化
    - 渲染器
    

    2.15简述drf中认证流程?

    2.16简述drf中节流的实现原理以及过程?匿名用户/非匿名用户 如何实现频率限制?

    2.17GenericAPIView视图类的作用?

    他提供了一些规则,例如:
    
    class GenericAPIView(APIView):
        serializer_class = None
        queryset = None
        lookup_field = 'pk'
        
        filter_backends = api_settings.DEFAULT_FILTER_BACKENDS
        pagination_class = api_settings.DEFAULT_PAGINATION_CLASS
        
        def get_queryset(self):
            return self.queryset
        
        def get_serializer_class(self):
            return self.serializer_class
        
    	def filter_queryset(self, queryset):
            for backend in list(self.filter_backends):
                queryset = backend().filter_queryset(self.request, queryset, self)
            return queryset
        
        @property
        def paginator(self):
            if not hasattr(self, '_paginator'):
                if self.pagination_class is None:
                    self._paginator = None
                else:
                    self._paginator = self.pagination_class()
            return self._paginator
        
    他相当于提供了一些规则,建议子类中使用固定的方式获取数据,例如:
    class ArticleView(GenericAPIView):
        queryset = models.User.objects.all()
        
        def get(self,request,*args,**kwargs):
            query = self.get_queryset()
    
    我们可以自己继承GenericAPIView来实现具体操作,但是一般不会,因为更加麻烦。
    而GenericAPIView主要是提供给drf内部的 ListAPIView、Create....
    class ListModelMixin:
        def list(self, request, *args, **kwargs):
            queryset = self.filter_queryset(self.get_queryset())
    
            page = self.paginate_queryset(queryset)
            if page is not None:
                serializer = self.get_serializer(page, many=True)
                return self.get_paginated_response(serializer.data)
    
            serializer = self.get_serializer(queryset, many=True)
            return Response(serializer.data)
        
    class ListAPIView(mixins.ListModelMixin,GenericAPIView):
        def get(self, request, *args, **kwargs):
            return self.list(request, *args, **kwargs)
    
    class MyView(ListAPIView):
        queryset = xxxx 
        ser...
    
    总结:GenericAPIView主要为drf内部帮助我们提供增删改查的类LIstAPIView、CreateAPIView、UpdateAPIView、提供了执行流程和功能,我们在使用drf内置类做CURD时,就可以通过自定义 静态字段(类变量)或重写方法(get_queryset、get_serializer_class)来进行更高级的定制。
    

    2.18jwt以及其优势。

    2.19序列化时many=True和many=False的区别?

    2.20应用DRF中的功能进行项目开发

    *****
    	解析器:request.query_parmas/request.data
    	视图
    	序列化
    	渲染器:Response
    
    ****
    	request对象封装
    	版本处理
    	分页处理
    ***
    	认证
    	权限
    	节流
    
    • 基于APIView实现呼啦圈
    • 继承ListAPIView+ GenericViewSet,ListModelMixin实现呼啦圈
  • 相关阅读:
    SpringBoot(八):SpringBoot中配置字符编码 Springboot中文乱码处理
    SpringBoot(二): SpringBoot属性配置文件 SpringBoot多环境配置文件 SpringBoot自定义配置文件
    使用Maven新建SpringBoot工程
    SpringBoot(四): SpringBoot web开发 SpringBoot使用jsp
    SpringBoot(三):SpringBoot热部署插件
    SpringBoot(六):SpringBoot中如何使用Servlet?
    ARQ自动重传请求与UDP提供可靠交付
    多线程程序中操作的原子性转帖
    多目录的Makefile
    VC++小小绘图程序
  • 原文地址:https://www.cnblogs.com/fengqiang626/p/11845202.html
Copyright © 2011-2022 走看看