zoukankan      html  css  js  c++  java
  • 接口、RESTful规范、DRF

    接口

    #接口:url连接,通过向链接发送不同的类型请求与参数得到相应的响应数据
    #1.在视图书写处理请求的 视图函数
    #2.在路由层为视图函数配置 url链接=>产生接口
    #3.前台通过ajax,爬虫,工具等对接口发送请求,提交相应的参数获得对应的响应数据
    # https://api.map.baidu.com/place/v2/search
    '''
    ak: 6E823f587c95f0148c19993539b99295
    region: 上海
    query: 肯德基
    output: json
    '''

    RESTful规范

    #定义接口的规范
    # REST:表征性状态转移(Representational State Transfer)
    #RESTful规范:web数据请求接口设计规范
    
    #学习的目的:
    #1.如何设计url链接地址
    #2.如何设计响应的数据格式
    
    '''
    1)通常使用https请求
    2)域名:有api关键字出现
        -- https://api.baidu.com (可能涉及跨越问题)
        -- https://baidu.com/api
    3)版本:不同版本需要标注
        -- https://example.com/api/v1 | -- https://example.com/api/1
        -- https://example.com/api/v2 | -- https://example.com/api/2
    4)资源:请求的目标数据称之为资源,资源一般都用名词复数表示
        -- https://example.com/api/v1/books  (之前不规范的案例: /get_books/)
    5)操作方式:不从请求链接体现操作方式,从请求方式上决定操作方式
        -- get:https://example.com/api/v1/books  获取所有
        -- post:https://example.com/api/v1/books  新增一本
        -- put:https://example.com/api/v1/book/1  更新id=1的一本
        -- patch:https://example.com/api/v1/book/1  更新id=1的一本
        -- delete:https://example.com/api/v1/book/1  删除id=1的一本
    6)资源过滤:通过接口传递参数来过滤资源
        -- https://example.com/api/v1/books?limit=10  限制10条
        
        
    7)状态码:返回数据要标准状态码,通过在数据中 {"status": 0}
        -- SUCCESS("0", "查询成功")
        -- NODATA("1xx", "非正确,无数据,显示基本信息")
        -- FEAILED("2xx", "查询失败")
    8)错误信息:请求失败需要标注错误信息  {"msg": "请求参数不合法"}
    9)操作结果:请求操作成功的返回结果 {"results": []}
        -- get:返回资源列表 | 返回单一资源
        -- post:返回单一新增资源
        -- put:返回更新的资源
        -- patch:返回更新的资源
        -- delete:返回空文档
    10)子资源返回资源接口:返回的资源如果有子资源,返回子资源的链接地址,如查找书,书的封面图片就可以url表示
    '''

    restful规范面试总结

    '''
    1.url链接设计:采用https方式,有api关键字,有版本需要明确版本,请求链接用名词来表示资源,具体的操作方式采用请求方式来确定
    2.url响应数据设计:需要明确状态码、错误信息、成功结果,子资源一般用子资源的接口来标注
    '''

    原生简易书写TESTful规范接口

    #路由层
    from app import views
    
    urlpatterns = [
        url(r'^books/', views.books),
    ]
    #视图层
    from django.http import JsonResponse
    book_list = [
        {
            'id': 1,
            'name': '三国演义'
        },
        {
            'id': 2,
            'name': '水浒传'
        }
    ]
    
    
    def books(request):
        if request.method == 'GET':
            ak = request.GET.get('ak', None)
            if not ak:
                return JsonResponse({
                    'status': 101,
                    'message': '没有明确ak',
                }, json_dumps_params={'ensure_ascii': False})
            return JsonResponse({
                'status': 0,
                'message': 'ok',
                'results': book_list
            }, json_dumps_params={'ensure_ascii': False})
        if request.method == 'POST':
            # return HttpResponse('post back')
            name = request.POST.get('name')
            id = len(book_list) + 1
            book = {'id': id, 'name': name}
            book_list.append(book)
            return JsonResponse({
                'status': 0,
                'message': 'ok',
                'results': book
            }, json_dumps_params={'ensure_ascii': False})

    CBV流程

    '''
    1)as_view()
        --User.as_view()本质拿到view(request,*args,**kwargs)函数对象
    2)view(request,*args,**kwargs)
        --return self.dispatch(request,*args,**kwargs)来完成请求的反射
    3)dispatch(request,*args,**kwargs)
        --完成具体的请求响应的分发
    #注:重写dispatch事可以再分发响应时,加入其他逻辑限制
    '''
    #路由层
    urlpatterns = [
        url(r'users/', views.Users.as_view())
    ]
    
    #视图层
    from django.views import View
    
    
    class Users(View):
        def dispatch(self, request, *args, **kwargs):
            pass  # 可以对请求加以限制
            result = super(Users, self).dispatch(request, *args, **kwargs)
            pass  # 可以对请求再近一步处理
            return result
    
        def get(self, request, *args, **kwargs):
            return JsonResponse({
                'message': 'get message'
            })
    
        def post(self, request, *args, **kwargs):
            return JsonResponse({
                'message': 'post message'
            })

    drf安装

    # drf:djangorestfraework => pip3 install djangorestfraework
    
    from rest_framework.views import APIView
    from rest_framework.request import Request
    from rest_framework.response import Response

    drf的安装步骤

    # 1)安装drf:pip3 install djangorestfraework
    # 2)settings.py 注册app:INSTALLED_APPS = [..., 'rest_framework']
    # 3)基于cbv完成满足RESTful规范的接口

    drf具体使用

    #路由层
    from app import views
    
    urlpatterns = [
        url(r'teachers/', views.Teachers.as_view())
    ]
    #视图层
    from rest_framework.views import APIView
    from rest_framework.response import Response
    
    
    class Teachers(APIView):
        def get(self, request, *args, **kwargs):
            # return JsonResponse({
            #     'status': 2,
            #     'message': '请求成功'
            # }, json_dumps_params={'ensure_ascii': False})
            salary = request.GET.get('salary')
            print(salary)
            return Response({
                'status': 2,
                'message': 'get请求成功'
            })
            # 前台发送数据的方式:formdata|urlencoded|json
        #drf的request都对其二次封装解析到request.data中
        def post(self, request, *args, **kwargs):
            print(request)
            print(request._request)
            salary = request.data.get('salary')
            print(salary)
            return Response({
                'status': 2,
                'message': 'post请求成功'
            })

    drf的请求源码分析

    # as_view()
        # 核心走了父类as_view
        view = super(APIView, cls).as_view(**initkwargs)
        # 返回的是局部禁用csrf认证的view视图函数
        return csrf_exempt(view)
        
    # dispatch(self, request, *args, **kwargs)
        # 二次封装request对象
        request = self.initialize_request(request, *args, **kwargs)
        # 自定义request规则
        self.initial(request, *args, **kwargs)
        
    # initialize_request(self, request, *args, **kwargs)
        # 原生request封装在request._request
        
    # initial(self, request, *args, **kwargs)
        # 认证
        self.perform_authentication(request)
        # 权限
        self.check_permissions(request)
        # 频率
        self.check_throttles(request)
        
    # 在drf的request.py的模块中,对django的request进行二次封装
        def __getattr__(self, attr):
            try:
                return getattr(self._request, attr)
            except AttributeError:
                return self.__getattribute__(attr)
        # 完成对django的request完全兼容

    drf序列化

    #models.py
    class Students(models.Model):
        name = models.CharField(max_length=32)
        age = models.IntegerField()
        gender = models.CharField(max_length=8)
    
        def __str__(self):
            return self.name
    #自定义序列化类:为具体的类提供序列化
    #my_serializers.py
    from rest_framework import serializers
    class StudentSerializers(serializers.Serializer)
      #1.如果没有source引入models的字段名,序列化字段名必须同models的字段名
      #2.如果有source引入models的字段名,序列化字段名必须不同于models的字段名,目的是对外隐藏数据库的字段名
        id = serializers.IntegerField()
        student_name = serializers.CharField(source='name')
        age = serializers.IntegerField()
        gender = serializers.CharField()
    # views.py
    from rest_framework.views import APIView
    from rest_framework.response import Response
    from app import models
    from app.my_serializers import StudentSerializers
    
    
    class Students(APIView):
        def get(self, request, *args, **kwargs):
            student_list = models.Students.objects.all()
                    # 需要序列化多个对象,需要明确many=True
            student_list = StudentSerializers(student_list, many=True)
            return Response({
                'status': 0,
                'message': 'ok',
                'results': student_list.data
            })
    
        def post(self, request, *args, **kwargs):
            name = request.data.get('name')
            age = request.data.get('age')
            gender = request.data.get('gender')
            student = models.Students.objects.create(name=name, age=age, gender=gender)
            student = StudentSerializers(student)
            return Response({
                'status': 0,
                'message': 'ok',
                'results': student.data
            })
    #urls.py
    urlpatterns = [
        url(r'students/', views.Students.as_view()),
    ]
  • 相关阅读:
    红蓝对抗之Windows内网渗透
    [框架漏洞]Thinkphp系列漏洞【截至2020-07-20】
    xss
    OWASP TOP 10 详解
    关于URL编码/javascript/js url 编码/url的三个js编码函数escape(),encodeURI(),encodeURIComponent()
    用C#实现的几种常用数据校验方法整理(CRC校验;LRC校验;BCC校验;累加和校验)
    批处理(.bat)简单应用实例
    线状地物图斑化全流程作业(使用ArcMap软件)
    VS Code Remote配置
    二分查找
  • 原文地址:https://www.cnblogs.com/ShenJunHui6/p/10872645.html
Copyright © 2011-2022 走看看