zoukankan      html  css  js  c++  java
  • drf框架--基础

    drf框架

    导入

    • http协议

      http协议是基于应用层的协议

      在发出请求时,需要具备请求首行,请求头,请求体

      特点:无状态无连接,且都是客户端先发起请求,服务端再进行响应

    • wsgi协议

      主要就是规定了数据的解析方式,把get之类的http请求解析封装到request里面

      在视图函数返回的时候,再把数据打包成http协议需要的格式传到前台

    什么是接口

    根据客户端传回的需求,进行路由匹配,调用相应的接口,然后接口执行完成的的数据,按照需要的格式进行返回。

    • 接口具有特定的url链接
    • 相应的请求方式:get、post、put、patch、delete
    • 前台请求的参数
    • 最后响应的结果

    restful接口规范

    1. 一般采用安全协议,因为接口都是对数据进行操作

    2. 在url中要体现接口的关键字api,如:

      http://api.baidu.comhttp://www.baidu.com/api

    3. 接口操作的数据称之为资源,前台请求数据的时候要采用资源的复数形式

      http://api.baidu.com/books/http://www.baidu.com/api/books

    4. 接口的链接中不能出现操作资源的方式,一般通过请求方式来决定操作资源的方式

      五大接口:

      • get:获取所有
      • get:获取一个
      • post:增加一个
      • put | patch:修改整体 | 修改部分
      • delete:删除一个
    5. 当资源数据有多个版本时,接口要做到版本控制

      http://api.baidu.com/books/v1/

    6. 资源响应的限制条件:筛选、排序……

      http://api.baidu.com/books/?publish=1&ordering=-price&limit=3

    7. 数据相应的状态码,类似于网络状态码,约定俗成为0,1,2

      {‘status’: 0 | 1 | 2}

      -- SUCCESS(0, "查询成功")
      -- NODATA(1, "非正确,无数据,显示基本信息")
      -- FEAILED(2, "查询失败")

    8. 响应的结果需要有信息描述

      {'status': 0, 'msg': 'success'}

    9. 响应的结果

      • get所有:返回所有的资源
      • get一个:返回一个资源
      • post增加一个:返回增加的资源
      • put | patch修改:返回修改的资源
      • delete:不做任何返回

    注意:需要通过接口文档告诉前台传递的必要和选填参数,以及返回的数据内容结构

    原生Django实现接口

    创建一个新的django项目,默认创建一个app,名为api

    # 主路由urls.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/urls.py
    
    from django.conf.urls import url
    from . import views
    urlpatterns = [
        # as_view() 本质拿到 view函数地址,
        # view内部通过dispatch分发请求给具体的(get|post|delete)方法处理请求
        # 处理完后的响应结果会一层层返回
        url(r'^books/$', views.BookView.as_view()),
        url(r'^books/(?P<pk>.*)/$', views.BookView.as_view()),
    ]
    
    # 模型层 api/models.py
    
    from django.db import models
    class Book(models.Model):
        name = 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 self.name
    # 模型层创建完成之后,完成数据库的迁移
    # python manage.py makemigrations
    # python manage.py migrate
        
    # 视图层 api/views
    from django.views import View
    from django.http import JsonResponse
    from . import models
    class BookView(View):
        def get(self, request, *args, **kwargs):
            pk = kwargs.get('pk')
            if pk:  # 通过是否有主键决定获取单个或是全部资源
                book_dic_list = models.Book.objects.filter(pk=pk).values('name', 'price')
                if not book_dic_list:
                    return JsonResponse({
                        'status': 2,
                        'msg': 'pk值有误',
                        'results': {}
                    })
                return JsonResponse({
                    'status': 0,
                    'msg': 'ok',
                    'results': book_dic_list[0]
                })
    
            book_dic_list = models.Book.objects.all().values('name', 'price')
            if not book_dic_list:
                return JsonResponse({
                    'status': 2,
                    'msg': '无数据',
                    'results': {}
                })
            return JsonResponse({
                'status': 0,
                'msg': 'ok',
                'results': list(book_dic_list)
            })
    

    drf框架

    • 安装

      pip install djangorestframework

    • 配置

      # 注册drf app
      # settings.py
      NSTALLED_APPS = [
          # ...
          'rest_framework',
      ]
      
    • 特点

      # 具体功能在具体模块下
      from rest_framework.request import Request
      from rest_framework.response import Response
      from rest_framework.exceptions import APIException
      from rest_framework.filters import OrderingFilter
      from rest_framework.views import APIView
      from rest_framework.pagination import PageNumberPagination
      from rest_framework.settings import APISettings
      
      
      # 自定义drf配置 - 在自己的settings.py
      REST_FRAMEWORK = {
          # 自定义修改drf的配置们
      }
      

    Django CBV 和drf CBV对比

    • Django CBV

      1. 继承了View视图类
      2. 通过as_view()来获取view函数地址
      3. 请求来了之后,调用view函数,内部调用dispatch函数完成请求的分发
      4. dispatch函数将请求方式映射成视图类的同名方法,完成请求的处理,得到相应、
      5. 最后将相应的结果一层层返回
    • drf CBV

      1. 继承了APIView
      2. 通过as_view()(继承自django的as_view)获取view函数地址,但在view函数中局部禁用了csrf认证
      3. 请求来了调用view函数,内部调用(APIView类的)dispatch函数完成请求分发
      4. dispatch函数 二次封装request进行三大认证后,再将请求方式映射成视图类的同名方法,完成请求的处理,得到相应,再对相应做渲染处理
      5. 最后将相应的结果一层层返回

    响应渲染模块

    就是返回数据的形式:json和浏览器接口页面

    分析

    # 入口: APIView类的dispatch函数
    self.response = self.finalize_response(request, response, *args, **kwargs)
    --> neg = self.perform_content_negotiation(request, force=True)
    --> renderers = self.get_renderers()
    --> self.renderer_classes
    --> APISetting:DEFAULT_RENDERER_CLASSES
    

    局部配置

    from rest_framework.views import APIView
    from rest_framework.response import Response
    
    from rest_framework.renderers import JSONRenderer
    from rest_framework.renderers import BrowsableAPIRenderer
    class UserAPIView(APIView):
        # 局部配置:只有该视图类起作用
        renderer_classes = [JSONRenderer]  # 只提供JSON数据渲染
        pass
    

    全局配置

    # drf配置
    REST_FRAMEWORK = {
        # 响应的渲染模块
        'DEFAULT_RENDERER_CLASSES': [
            'rest_framework.renderers.JSONRenderer',
            'rest_framework.renderers.BrowsableAPIRenderer',
        ],
    }
    

    请求数据解析模块

    前端请求的数据进行解析的方式:json、form-data、urlencoding

    分析

    # 入口:APIView类的dispatch函数
    request = self.initialize_request(request, *args, **kwargs)
    --> parsers=self.get_parsers()
    --> self.parser_classes
    --> APISetting:DEFAULT_PARSER_CLASSES
    

    局部配置

    from rest_framework.views import APIView
    from rest_framework.response import Response
    
    from rest_framework.parsers import JSONParser
    from rest_framework.parsers import FormParser
    from rest_framework.parsers import MultiPartParser
    class UserAPIView(APIView):
        # 局部配置:只有该视图类起作用
        parser_classes = [JSONParser]  # 只提供JSON解析
        pass
    

    全局配置

    # drf配置
    REST_FRAMEWORK = {
        # 请求数据解析模块
        'DEFAULT_PARSER_CLASSES': [
            'rest_framework.parsers.JSONParser',  # 'application/json'
            'rest_framework.parsers.FormParser',  # 'application/x-www-form-urlencoded'
            'rest_framework.parsers.MultiPartParser'  # multipart/form-data
        ],
    }
    

    请求的数据解析的位置

    1. 如果是数据包,则都解析到request.data中
    2. 如果是url中/?参数则解析到request.query_params中

    响应模块

    # 响应可以设置响应数据、响应网络状态码、响应头、响应数据类型等
    data = {
        'status': 0,
        'msg': 'get ok',
        'results': [],
        'token': '123.12321.231'
    }
    return Response(
        data=data,
        status=status.HTTP_200_OK,
        headers={'Token': '123as.masd21.asd213sd'},
        content_type='application/json'  # 默认就是application/json
    )
    

    二次封装Response

    from rest_framework.response import Response
    
    class APIResponse(Response):
        def __init__(self, data_status, data_msg, results=None, status=None, headers=None, content_type=None, **kwargs):
            data = {
                'status': data_status,
                'msg': data_msg
            }
            
            if results is not None:
                data['results'] = results
                
            data.update(kwargs)
            
            super().__init__(data=data, status=status, headers=headers, content_type=content_type)
    
  • 相关阅读:
    Spring过滤器和拦截器 2017-12-20
    集合
    用LinkedList方法模拟栈的数据结构
    集合遍历时,修改元素
    Calendar日历类,简单的时间获取
    java中日期与字符串之间的转换
    UIViewController生命周期
    属性传值和代理传值的步骤
    UITableView的详细使用
    UIAlertView的使用方法
  • 原文地址:https://www.cnblogs.com/Hades123/p/11455876.html
Copyright © 2011-2022 走看看