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

    drf 基础
       1.接口:什么 是接口 restful接口规范
        2、CBV生命周期源码 - 基于restful规范下的CBV接口
        3、请求组件、解析组件、响应组件
        4、序列化组件(灵魂)
        5、三大认证(重中之重):认证、权限(权限六表)、频率
        6、其他组件:过滤、筛选、排序、分页、路由

    接口:

    '''
    接口:联系两个物质的媒介,完成信息交互
    web程序中:联系前台页面与后台数据库的媒介
    web接口组成:
        url:长的像返回数据的url链接
        请求参数:前台按照指定的key提供数据给后台
        响应数据:后台与数据库交互后将数据反馈给前台
    '''

    restful接口规范

      

    接口规范:就是为了采用不同的后台语言,也能使用同样的接口获取到同样的数据
    
    如何写接口:接口规范是 规范化书写接口的,写接口要写 url、响应数据
    
    ​        注:如果将请求参数也纳入考量
     
    
    
    
    范围,那就是在写 接口文档
    
    两大部分:
      url
       1,用api关键字标识接口url
        api.baidu.com | www.baidu.com/api
       2,接口数据安全性决定优先选择https协议
       3,如果一个接口有多个版本存在,需要在url中标识体现
         api.baidu.com/v1/... | api.baidu.com/v2/...
       4,接口操作的数据源称之为 资源,在url中一般采用资源复数形式,一个接口可以概括对该资源的多种操作方式
         api.baidu.com/books | api.baidu.com/books/(pk) 
       
        5) 请求方式有多种,用一个url处理如何保证不混乱 - 通过请求方式标识操作资源的方式
           /books  get   获取所有
            下面的四个完全兼容get请求
           /books  post  增加一个(多个)
           /books/(pk) delete  删除一个
            /books/(pk) put   整体更新一个
            /books/(pk) patch  局部更新一个
    
    
        6) 资源往往涉及数据的各种操作方式 - 筛选、排序、限制
           api.baidu.com/books/?search=西&ordering=-price&limit=3
      响应方式:
        1) http请求的响应会有响应状态码,接口用来返回操作的资源数据,可以拥有 操作数据结果的 状态码
           status  0(操作资源成功)  1(操作资源失败)  2(操作资源成功,但没匹配结果)
           注:资源状态码不像http状态码,一般都是后台与前台或是客户约定的
          数据状态码: 例如:status  0(操作资源成功) 
          数据提示:   例如: msg:登录失败
          资源本身:要返回的资源 
        2) 资源的状态码文字提示
           status  ok '账号有误'  '密码有误'  '用户锁定'
     
        3) 资源本身
           results
           注:删除资源成功不做任何数据返回(返回空字符串)
     
        4) 不能直接返回的资源(子资源、图片、视频等资源),返回该资源的url链接
        
        总结:接口由两部分组成:url(其实就是一个接口),响应数据.请求数据
           url:
            1,首相遵循restful接口规范协议
            2,在url前要加上https:决定接口数据的安全性(头)
            3,用api关键字标识接口url
            4,接口操作资源(数据),通常以复数显示,里面包括对该资源的多种操作方式(get,post,delete,put,patch)
           响应数据:
            1,status,资源状态码
            2,资源的状态码文本提示:
            3,资源本身:即要返回给前端的数据
              ps:不能直接返回的资源有图片,视频,子资源
              通过请求方式(get|post|update|patch|delete)来操作资源,还有在url中可以对数据进行限制 ,排序等等

                通过发送请求,可以拿到后台按照规范的响应数据,数据是一个超大的{}
                  资源状态码
                  资源的状态码文本提示
                  result资源本身
                 案列{
                    'status':0,
                    'msg':'ok',
                    'result':[{
                       'title':*,
                       'price':*,
                       'img':https://* 
                      }]

      

    基于restful规范的原生Django接口

    主路由: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
    # Create your views here.
    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_list_obj = models.Book.objects.all()
                # 序列化过程
                book_list = []
                for obj in book_list_obj:
                    print(obj)
                    # 把数据转化为字典格式,解压赋值
                    dic = {}
                    dic['title'] = obj.title
                    dic['price'] = obj.price
                    book_list.append(dic)
                    #返回 响应数据
                return JsonResponse({
                    'status':0,
                    'msg':'ok',
                    'result':book_list    # 后端处理后的数据
                },json_dumps_params={'ensure_ascii':False})  # 转换为前端识别的json格式
    
            else:       # 单查
                book_dic = models.Book.objects.filter(pk=pk).values('title','price').first()
                if book_dic:
                    return JsonResponse({
                        'status':0,
                        'msg':'ok',
                        'result':book_dic,
                    },json_dumps_params={'ensure_ascii':False})
                return JsonResponse({
                    'status': 2,
                    'msg': '无结果',
                    }, json_dumps_params={'ensure_ascii': False})
    
        # postman 可以完成不同方式的请求:get|post|put....
        # postman 发送数据包的方式有三种:form-data|urlencoding|json
        # 原生django对urlencoding方式数据兼容最好
    
    
        def post(self,request,*args,**kwargs):
            print(request.POST)     #<QueryDict: {'title': ['三国演义'], 'price': ['2.99']}>
            print(request.body)
            res = request.POST
            print(res.dict())
            # 前台通过urlencoding方式提交数据
            try:                                            # **request.POST.dict() 打散,request拥有dict方法
                book_obj = models.Book.objects.create(**request.POST.dict())
                if book_obj:
                    return JsonResponse({
                        'status':0,
                        'msg':'ok',
                        # 获取前端数据,把真实数据字典赋值
                        'result':{'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})

    Postman接口工具

      官网下载安装

      get请求,携带参数采用Params

      post等请求,提交数据包可以采用三种方式:form-date、urlencoding、json

      所有请求都可以携带请求头

     

    DRF框架

      安装:在pycharm命令行: pip3 install djangorestframework

      drf框架规矩的封装风格

      注册:在settings.py文件中进行注册:

          

    INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'api.apps.ApiConfig',
       # 在这里进行注册
    'rest_framework',
    ]
    from rest_framework.views import APIView
    from rest_framework.response import Response
    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) 请求走的是APIView的as_view函数

      2) 在APIView的as_view调用父类(django原生)的as_view,还禁用了 csrf 认证

      3) 在父类的as_view中dispatch方法请求走的又是APIView的dispatch
        1,其中有一句:
          view = super().as_view(**initkwargs)
          自定义类继承了APIView,在调用时 会走as_view()方法,但是APIView中没有as_view方法,又因为APIView
          它继承了View类,在View类中存在as_view()方法,所以此时走的就是View类中存在as_view()方法
        2,在View类中存在as_view()方法中
          return self.dispatch(request, *args, **kwargs)
          此时的self就是Test,所以此时调用的就是父类的dispatch方法,
     
      4) 完成任务方法交给视图类的请求函数处理,得到请求的响应结果,返回给前台
        ps:如果继承了 APIView所有的子类,就默认将csrf的中间件给禁用了(即帮你注释了),
          因为他自己有认证,他的认证比这高级,而且还可以自定义
        在混用的时候,csrf对于原生的django还是使用的,只有继承了APIView的子类,才会拥有drf认证
        总结:继承了APIView的视图类,会禁用csrf认证
    class APIView(View):

    # The following policies may be set at either globally, or per-view.
    # 渲染模块renderer_classes
    renderer_classes = api_settings.DEFAULT_RENDERER_CLASSES
    # 解析模块
    parser_classes = api_settings.DEFAULT_PARSER_CLASSES
    # 认证模块
    authentication_classes = api_settings.DEFAULT_AUTHENTICATION_CLASSES

    throttle_classes = api_settings.DEFAULT_THROTTLE_CLASSES
    permission_classes = api_settings.DEFAULT_PERMISSION_CLASSES
    content_negotiation_class = api_settings.DEFAULT_CONTENT_NEGOTIATION_CLASS
    metadata_class = api_settings.DEFAULT_METADATA_CLASS
    versioning_class = api_settings.DEFAULT_VERSIONING_CLASS
        def dispatch(self, request, *args, **kwargs):
            """
            `.dispatch()` is pretty much the same as Django's regular dispatch,
            but with extra hooks for startup, finalize, and exception handling.
            """
            # 在这里是对象获取自己的属性
            self.args = args
            self.kwargs = kwargs
            request = self.initialize_request(request, *args, **kwargs)
            self.request = request
            self.headers = self.default_response_headers  # deprecate?
    
            try:
                # 下面这句话执行出异常就会走drf提供的异常 response = self.handle_exception(exc)
                self.initial(request, *args, **kwargs)
    
                # Get the appropriate handler method
                if request.method.lower() in self.http_method_names:
                    handler = getattr(self, request.method.lower(),
                                      self.http_method_not_allowed)
                else:
                    # 原生django提供的异常
                    handler = self.http_method_not_allowed
    
                response = handler(request, *args, **kwargs)
            # drf提供的异常
            except Exception as exc:
                #原生的数据
                response = self.handle_exception(exc)
            # 在这里判断是浏览器发来的还是页面发来的(请求方式)再加以包装最终返回数据
            self.response = self.finalize_response(request, response, *args, **kwargs)
            return self.response
                
     
     
     
     

     

  • 相关阅读:
    vue2 下载scss依赖包
    fastjson使用
    vscode format
    flutter 中涉的深拷贝
    通过pom给maven添加编译插件
    IDEA添加动态模板(Live Templates)
    Maven启动tomcat:run异常
    Redis
    tomcat启动时启动窗口出现乱码的解决方案
    无效的源发行版,解决方案
  • 原文地址:https://www.cnblogs.com/Fzhiyuan/p/11673989.html
Copyright © 2011-2022 走看看