zoukankan      html  css  js  c++  java
  • drf框架相关

    drf框架: django-rest framework
    
    1.接口:联系两个物质的媒介,完成信息交互
        web程序中:联系前台页面与后台数据库的媒介,已完成信息的交互;
        web接口组成:
            url:长得像放回数据的url链接
            请求参数:前台按照指定的key提供数据给后台
            响应数据:后台与数据库交互后将数据反馈给前台 
    2.restful接口规范 -> 规范化书写接口
        定义:为了采用不同的后台语言,也能用同样的接口来获取到同样的数据;
        接口文档: 写接口要写 url,响应数据
            注:如果将请求参数也纳入考量范围,那就是写接口文档
            
        .url:
            1.用api关键字标识接口url     eg:api.baidu.com | www.baidu.com/api
            2.接口数据安全性决定优先选择https协议
            3.如果一个接口有多版本存在,需要在url中标识提现
               eg:    api.baidu.com/v1/...   | api.baidu.com/v2/...
            4.接口操作的数据源称之为资源,在url中一般采用资源复数形式,
              一个接口可以概括对该资源的多种操作方式
              api.baidu.com/books | api.baidu.com/books/(pk)
            5.请求方式有多种,如何用一个url处理保证不混乱?
              --通过请求方式标识操作资源的方式
                  /books        get            获取所有
                /books        post        增加一个(多个)
                /books/(pk)    delete        删除一个
                /books/(pk)    put            整体更新一个
                /books/(pk)    patch        局部更新一个
                      
                      
            6.资源往往涉及数据的各种操作方式 --筛选,排序,限制
                eg: api.baidu.com/books/?search=系&ordering=price&limit=3
                
        .响应数据:
            1.http请求的响应会有不同的状态码,接口用来返回操作的资源数据
                status  0(操作资源成功)  1(操作资源失败)  2(操作资源成功,但没匹配结果)
                注:资源状态码不像http状态码,一般都是后台与前台约定的
            2.资源的状态码文字提示
                status  ok  子账号有误'   '密码有误'   '用户锁定'
            3.资源本身
                results
                注: 删除资源成功不做任何数据返回
                
            4.不能直接放回的资源(子资源,图片,视频),返回资源的链接
    3.cbv生命周期源码  --基于restful规范下的cbv接口
    基础接口:
        #主路由:url.py
            from django.conf.urls import url, include
            from django.contrib import admin
            urlpatterns = [
                url(r'^admin/', admin.site.urls),
                # 路由分发
                url(r'^api/', include('api.urls'))
            ]
        #api组件的子路由:api/url.py
            from django.conf.urls import url
            from . import views
            urlpatterns = [
                url(r'^books/', views.Book.as_view()),
                url(r'^books/(?P<pk>.*)/$', views.Book.as_view()),
            ]
        #模型层:model.py
            from django.db import models
            class Book(models.Model):
                title = models.CharField(max_length=64)
                price = models.DecimalField(max_digits=5, decimal_places=2)
                class Meta:
                    db_table = 'old_boy_book'
                    verbose_name = '书籍'
                    verbose_name_plural = verbose_name
                def __str__(self):
                    return '《%s》' % self.title
        #后台层:admin.py
            from django.contrib import admin
            from . import models
            admin.site.register(models.Book)
    
        #数据库迁移
             python manage.py makemigrations
             python manage.py migrrate
             #注册超级管理员
             python manage.py createsuperuser
        #视图层:views.py
            from django.http import JsonResponse
            from django.views import View
            from . import models
                class Book(View):
                    def get(self, request, *args, **kwargs):
                        pk = kwargs.get('pk')
                        if not pk:  # 群查
                            # 操作数据库
                            book_obj_list = models.Book.objects.all()
                            # 序列化过程
                            book_list = []
                            for obj in book_obj_list:
                                dic = {}
                                dic['title'] = obj.title
                                dic['price'] = obj.price
                                book_list.append(dic)
                            # 响应数据
                            return JsonResponse({
                                'status': 0,
                                'msg': 'ok',
                                'results': book_list
                            }, json_dumps_params={'ensure_ascii': False})
                        else:  # 单查
                            book_dic = models.Book.objects.filter(pk=pk).values('title', 'price').first()
                            if book_dic:
                                return JsonResponse({
                                    'status': 0,
                                    'msg': 'ok',
                                    'results': book_dic
                                }, json_dumps_params={'ensure_ascii': False})
                            return JsonResponse({
                                'status': 2,
                                'msg': '无结果',
                            }, json_dumps_params={'ensure_ascii': False}
        1.获取一个
        2.获取所有
        3.增加一个
        4.删除一个
        5.整体更新一个
        6.局部更新一个
        群增|群删|整体改群改|局部改群
            def get(self, request, *args, **kwargs):
                pk = kwargs.get('pk')
                if not pk:  # 群查
                    # 操作数据库
                    book_obj_list = models.Book.objects.all()
                    # 序列化过程
                    book_list = []
                    for obj in book_obj_list:
                        dic = {}
                        dic['title'] = obj.title
                        dic['price'] = obj.price
                        book_list.append(dic)
                    # 响应数据
                    return JsonResponse({
                        'status': 0,
                        'msg': 'ok',
                        'results': book_list
                    }, json_dumps_params={'ensure_ascii': False})
                else:  # 单查
                    book_dic = models.Book.objects.filter(pk=pk).values('title', 'price').first()
                    if book_dic:
                        return JsonResponse({
                            'status': 0,
                            'msg': 'ok',
                            'results': book_dic
                        }, json_dumps_params={'ensure_ascii': False})
                    return JsonResponse({
                        'status': 2,
                        'msg': '无结果',
                    }, json_dumps_params={'ensure_ascii': False})
                    
    Postman接口工具:    
    postman可以完成不同方式的请求: get|post|put...
    get请求,携带参数采用Params,
    post请求提交数据包有三种方式:form-data | urlencoding | json
    原生django对urlencoding方式数据兼容最好
        def post(self, request, *args, **kwargs):
            # 前台通过urlencoding方式提交数据
            try:
                book_obj = models.Book.objects.create(**request.POST.dict())
                if book_obj:
                    return JsonResponse({
                        'status': 0,
                        'msg': 'ok',
                        'results': {'title': book_obj.title, 'price': book_obj.price}
                    }, json_dumps_params={'ensure_ascii': False})
            except:
                return JsonResponse({
                    'status': 1,
                    'msg': '参数有误',
                }, json_dumps_params={'ensure_ascii': False})
    
            return JsonResponse({
                'status': 2,
                'msg': '新增失败',
            }, json_dumps_params={'ensure_ascii': False})
    
    
    DRF框架:
        安装: pip install djangorestframework
        drf框架规矩的封装风格:
            from rest_framework.views import APIView
            from rest_framework.response import Pesponse
            from rest_framework.request import Request
            from rest_framework.serializers import Serializer
            from rest_framework.settings import APISettings
            from rest_framework.filters import SearchFilter
            from rest_framework.pagination import PageNumberPagination
            from rest_framework.authentication import TokenAuthentication
            from rest_framework.permissions import IsAuthenticated
            from rest_framework.throttling import SimpleRateThrottle
            
        class Test(APIView):
            def get(self, request, *args, **kwargs):
                return Response('drf get ok')
        
        drf请求生命周期:
            1.请求走的是APVIiew 的 as_view函数
            2.在APIView的 as_view 调用父类(django原生)的as_view,还禁用了 csrf 认证
            3.在父类的 as_view中dispatch方法请求走的又是APIV接我的dispatch
            4.完成任务方法交给视图类的请求函数处理,得到请求的响应结果,返回给前台
    
        请求模块: request对象:
            源码入口:APIView类的dispatch方法中:
            源码分析:
                #二次封装得到def的request对象
                request = self.initialize_request(request,*args,**kwargs)
                #在rest_framework.request.Request实例化方法中
                self_request = request 将request作为新request的_request属性
                #在rest_framework.request.Request的__getattr__方法中
                try:
                    return getattr(self._request,attr) #访问属性完全兼容原生request
                except AttributeError:
                    return self.__getattrigute__(attr)
    
            小结:
                1.drf对原生request做了二次封装,request._request就是原生request
                2.原生request对象的属性和方法都可以被drf的request对象直接访问(兼容)
                3.drf请求的所有url拼接参数均被解析到query_params中,所有数据包数据都被解析到data中 
                
            class Test(APIView):
                def get(self, request, *args, **kwargs):
                    # url拼接的参数
                    print(request._request.GET)  # 二次封装方式
                    print(request.GET) # 兼容
                    print(request.query_params) # 拓展
    
                    return Response('drf get ok')
    
                def post(self, request, *args, **kwargs):
                    # 所有请求方式携带的数据包
                    print(request._request.POST)  # 二次封装方式
                    print(request.POST)  # 兼容
                    print(request.data)  # 拓展,兼容性最强,三种数据方式都可以
    
                    print(request.query_params)
    
                    return Response('drf post ok')
    
    
        渲染模块:浏览器和Postman请求结果渲染数据的方式不一样
            源码入口:APIView类的dispatch方法中:self.response = self.finalize_response(request, response, *args, **kwargs)
            源码分析:
                #解析reponse对象数据
                self.response = self.finalize_response_response(request,response,*args,**kwargs)点进去
                #拿到运行的解析类的对象萌:
                neg = self.perform_content_negotiation(request,force=True) 点进去
                #获取解析类对象
                renderers = self.get_genderers() 点进去
                #从视图类中得到renderer_classes请求类,如何实例化一个个对象形参解析类对象列表
                return [renderer() for renderer in self.renderer_classes]
        
        重点:self.renderer_classes获取renderer_rendererd_classes的顺序
            1.自己视图类的类属性(局部配置) =>
            2.APIView类的类属性设置 =>
            3.自己配置文件的DEFAULT_RENDERER_CLASSES(全局配置) =>
            4.drf配置文件的DEFAULT_RENDERER_CLASSES
            
        全局配置:所有视图类统一处理,在项目的settings.py中    
            REST_FRAMEWORK = {
                # drf提供的渲染类
                'DEFAULT_RENDERER_CLASSES': [
                    'rest_framework.renderers.JSONRenderer',
                    'rest_framework.renderers.BrowsableAPIRenderer',
                ],
            }
        局部配置:某一个或一些实体类单独处理,在views.py视图类中提供对应的类属性
            from rest_framework.renderers import JSONRenderer
            class Test(APIView):
                def get(self, request, *args, **kwargs):
                    return Response('drf get ok')
    
                def post(self, request, *args, **kwargs):
                    return Response('drf post ok'
            class Test2(APIView):
                # 局部配置
                renderer_classes = [JSONRenderer]
                def get(self, request, *args, **kwargs):
                    return Response('drf get ok 2')
    
                def post(self, request, *args, **kwargs):
                    return Response('drf post ok 2')
    APIView与View的不同之处在于:
    
        1.传入到视图方法中的是REST framework的Request对象,而不是Django的HttpRequeset对象;
        2.视图方法可以返回REST framework的Response对象,视图会为响应数据设置(render)符合前端要求的格式;
        3.任何APIException异常都会被捕获到,并且处理成合适的响应信息;
        4.在进行dispatch()分发前,会对请求进行身份认证、权限检查、流量控制。
    
    支持定义的属性
        authentication_classes 列表或元祖,身份认证类
        permissoin_classes 列表或元祖,权限检查类
        throttle_classes 列表或元祖,流量控制类
    
    
    
  • 相关阅读:
    iOS 十六进制字符串 "#FFFF00" 转换成颜色对象
    iOS toast 的连续显示
    文件管理
    pod 常用命令
    键盘事件
    iOS 添加阴影
    渐变色
    Ubuntu安装flameshot截图工具
    Ubuntu安装酸酸乳客户端
    Ubuntu安装网易云音乐
  • 原文地址:https://www.cnblogs.com/wyf20190411-/p/11674054.html
Copyright © 2011-2022 走看看