zoukankan      html  css  js  c++  java
  • drf1

    复习

    """
    1、vue如果控制html
    	在html中设置挂载点、导入vue.js环境、创建Vue对象与挂载点绑定
    	
    2、vue是渐进式js框架
    
    3、vue指令
    	{{ }}
    	v-text|html => 限制一次性渲染 v-once
    	v-if|show
    	v-if v-else-if v-else
    	v-for
    	v-model
    	v-bind  [c1, c2] | {active: isActive}:class={xxx:yy}
    	v-on fn | fn(...) | fn($event, ...)
    	
    	{{ data中出现的变量 }}  v-if="data中出现的变量 的条件表达式"
    	
    4、vue实例成员
    	el | template
    	components
    	data {} | data () { return {} }
    	methods
    	computed:定义的是方法属性
    	watch:监听属性
    	props
    	
    	<div id="app">
    		<Nav :subdata="supdata" @subaction="supaction"></Nav>
    	</div>
    	
    5、生命周期钩子
    	都是实例成员,在组件创建到销毁整个过程的某些时间节点回调的函数
    	
    	beforeCreated() {
    		this._fn => this.$option.methods._fn
    	}
    	
    6、项目
    	环境:node => npm(cnpm) => vue/cli
    	创建与配置 vue create proj | 选择基础插件 | 配置npm启动
    	插件:vue-router | vuex | axios | vue-cookies | element-ui
    """
    

    drf框架

    全称:django-rest framework

    知识点

    """
    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			获取所有
    	/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状态码,一般都是后台与前台或是客户约定的
    	
    2) 资源的状态码文字提示
    	status  ok	'账号有误'  '密码有误'  '用户锁定'
    	
    3) 资源本身
    	results
    	注:删除资源成功不做任何数据返回(返回空字符串)
    	
    4) 不能直接返回的资源(子资源、图片、视频等资源),返回该资源的url链接
    

    基于restful规范的原生Django接口

    CBV+路由分发

    主路由:url.py
    from django.conf.urls import url, include
    from django.contrib import admin
    
    
    urlpatterns = [
        url(r'^admin/', admin.site.urls),
        # 路由分发,在后面访问的地址为http://127.0.0.1:8000/api/books/,api就是路由分发的文件夹的名字
        url(r'^api/', include('api.urls'))
    ]
    

    路由分发之后访问的地址就变成:!!!

    http://127.0.0.1:8000/app01/books
    
    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()),#这个话是对上句话的补充,两个链接指向的地址是同一个。这句话就是url地址在books写任意的内容都能访问到同样的地址。
        有名分组的名字就是后台对应请求的kwargs中的k:例如{'pk': 'fdadfad'}
    ]
    # a* 可以匹配 a aa aaa aaaa aaaaaaa等等
    # .*:就是说匹配a任意次数
    
    模型层: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 #在视图层查询数据库要导入models!!!记住
    
    
    # 六大基础接口:获取一个 获取所有 增加一个 删除一个 整体更新一个 局部更新一个
    # 十大接口:群增 群删 整体改群改 局部改群改
    class Book(View):
        def get(self, request, *args, **kwargs):# kwargs是字典
            pk = kwargs.get('pk')
            if not pk:  # 群查
                # 操作数据库
                book_obj_list = models.Book.objects.all()
                # 序列化过程
                book_list = []
                for obj in book_obj_list: # 注意for这个dic必须在for循环里面!!!
                    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:  # 单查 filter查询需要查询的pk不存在时,不会报错!
                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可以完成不同方式的请求:get | post | put ...
        # postman发送数据包有三种方式:form-data | urlencoding | json
        # 原生django对urlencoding方式数据兼容最好
        def post(self, request, *args, **kwargs):
            # 前台通过urlencoding方式提交数据
            try:# 下面的.dict()以前没用过,可以将对象转换成字典!!!;
                # 并且这个新增的方法是通过源码得出的
                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})
    

    Postman接口工具

    官网下载安装

    get请求,携带参数采用Params

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

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

    发送post请求,数据在body里写,并且以json格式(双引号)

    后台在post请求的body中接受,要注意,post请求要注释csrf

    原django接收到信息:

    b'{
    	"title":"xe5xa4xa7xe8xafx9dxe8xa5xbfxe6xb8xb8",
    	"price":123
    }'
    

    urlencoding解析的最好

    print(request.POST)<QueryDict: {'title': ['大话西游1']}>
    print(request.body)b'title=%E5%A4%A7%E8%AF%9D%E8%A5%BF%E6%B8%B81'
    

    form-date直接报错

    发送json格式的情况:是后台post请求中没有信息,都在body里

    DRF框架

    安装
    >: pip3 install djangorestframework
    
    Django中注册
    INSTALLED_APPS = [
    	'rest_framework'
    ]
    
    drf框架规矩的封装风格
    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')# 这里必须写Response
    
    drf请求生命周期
    """
    1) 请求走的是APIView的as_view函数
    
    2) 在APIView的as_view调用父类(django原生)的as_view,还禁用了 csrf 认证
    
    3) 在父类的as_view中dispatch方法请求走的又是APIView的dispatch
    
    4) 完成任务方法交给视图类的请求函数处理,得到请求的响应结果,返回给前台
    """
    

    请求模块:request对象

    源码入口

    APIView类的dispatch方法中:request = self.initialize_request(request, *args, **kwargs)

    源码分析
    """
    # 二次封装得到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.__getattribute__(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):
            # 所有请求方式携带的数据包。以下三个得到的数据结果相同,前两个只有json数据为空
            print(request._request.POST)  # 二次封装方式
            print(request.POST)  # 兼容
            print(request.data)  # 拓展,兼容性最强,三种数据方式都可以。formdata,urlencoded,json
            print(request.query_params)#post携带的参数pararms
            return Response('drf post ok')
    

    渲染模块:浏览器和Postman请求结果渲染数据的方式不一样

    源码入口

    APIView类的dispatch方法中:self.response = self.finalize_response(request, response, *args, **kwargs)

    源码分析
    """
    # 最后解析reponse对象数据
    self.response = self.finalize_response(request, response, *args, **kwargs) 点进去
    
    # 拿到运行的解析类的对象们
    neg = self.perform_content_negotiation(request, force=True) 点进去
    
    # 获得解析类对象
    renderers = self.get_renderers() 点进去
    
    # 从视图类中得到renderer_classes请求类,如何实例化一个个对象形参解析类对象列表
    return [renderer() for renderer in self.renderer_classes]
    
    
    # 重点:self.renderer_classes获取renderer_classes的顺序
    #	自己视图类的类属性(局部配置) => 
    #	APIView类的类属性设置 => 
    #	自己配置文件的DEFAULT_RENDERER_CLASSES(全局配置) => 
    #	drf配置文件的DEFAULT_RENDERER_CLASSES
    """
    
    全局配置:所有视图类统一处理,在项目的settings.py中
    REST_FRAMEWORK = {
        # drf提供的渲染类
        'DEFAULT_RENDERER_CLASSES': [
            'rest_framework.renderers.JSONRenderer',
            'rest_framework.renderers.BrowsableAPIRenderer',
        ],
    }
    
    局部配置:某一个或一些实体类单独处理,在views.py视图类中提供对应的类属性
    class Test(APIView):
        def get(self, request, *args, **kwargs):
            return Response('drf get ok')# 由jsonresponse换成response
    
        def post(self, request, *args, **kwargs):
            return Response('drf post ok')
    
    # 在setting.py中配置REST_FRAMEWORK,完成的是全局配置,所有接口统一处理
    # 如果只有部分接口特殊化,可以完成 - 局部配置。
    # 现在这个test连接中的配置由renderer_classes控制
    from rest_framework.renderers import JSONRenderer
    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')
    
  • 相关阅读:
    Go 语言简介(下)— 特性
    Array.length vs Array.prototype.length
    【转】javascript Object使用Array的方法
    【转】大话程序猿眼里的高并发架构
    【转】The magic behind array length property
    【转】Build Your own Simplified AngularJS in 200 Lines of JavaScript
    【转】在 2016 年做 PHP 开发是一种什么样的体验?(一)
    【转】大话程序猿眼里的高并发
    php通过token验证表单重复提交
    windows 杀进程软件
  • 原文地址:https://www.cnblogs.com/ZDQ1/p/11676830.html
Copyright © 2011-2022 走看看