django rest framework restful 规范

时间:2022-11-25 19:35:06

 

内容回顾:
    1. django请求生命周期
        
        -> 执行遵循wsgi协议的模块(socket服务端)
        -> 中间件(路由匹配)
        -> 视图函数(业务处理:ORM、模板渲染)
        -> 中间件
        -> wsgi返回
        
    2. 什么wsgi
        web服务网关接口
        实现该协议的模块:
            - wsgiref
            - werkzurg
            - uwsig

    3. 视图
        - FBV
            url - 函数 
        - CBV 
            url - view
    
    4. djang rest framework
        
    
    5. restful 规范(10)
        什么是接口?
            - URL
            - 约束
                # 约束继承(实现)了他的类中必须含有IFoo中的方法
                interface IFoo:
                    def func(self): pass 
                    
                    
                class Foo(IFoo):
                    def func(self): 
                        print(11111)
        

        1. 根据method不同,进行不同操作
            GET/POST/PUT/DELETE/PATCH
        2. 面向资源编程
            http://www.luffycity.com/salary
        
        3. 体现版本
            http://www.luffycity.com/v1/salary
            http://www.luffycity.com/v2/salary
            
            https://v4.bootcss.com/
            https://v3.bootcss.com/
        4. 体现是API
            http://www.luffycity.com/api/v1/salary
            http://www.luffycity.com/api/v2/salary    
            
            http://api.luffycity.com/v1/salary    
            http://api.luffycity.com/v2/salary    
        5. https
            https://www.luffycity.com/api/v1/salary
            https://www.luffycity.com/api/v2/salary    
            
        6. 响应式设置状态码
            200
            300
            400
            500
            return HttpResponse('adfasdf',status=300)
        
        7. 条件 
            https://www.luffycity.com/api/v2/salary?page=1&size=10
        
        8. 返回值
            https://www.luffycity.com/api/v2/salary
            GET: 所有列表
            {
                code: 10000,
                data: [    
                    {'id':1,'title':'高亮'},
                    {'id':1,'title':'龙泰'},
                    {'id':1,'title':'小东北'},
                ]
            }
                
            POST: 返回新增的数据
                {'id':1,'title':'高亮'}
                
            https://www.luffycity.com/api/v2/salary/1/
            GET: 获取单条数据
                    {'id':1,'title':'高亮'}
            PUT:更新
                    {'id':1,'title':'高亮'}
            PATCH: 局部更新
                    {'id':1,'title':'高亮'}
            DELETE:删除
                
        9. 返回错误信息
            {
                code: 100001,
                error: 'xxx错误'
            }
        
        10. Hypermedia API
            ret = {
                code: 1000,
                data:{
                    id:1,
                    name:'小强',
                    depart_id:http://www.luffycity.com/api/v1/depart/8/
                }
            }
    
        建议大家使用restful规范
        
        
    6. django rest framework框架(10- 权限
        - 认证
        - 访问频率限制
        - 序列化
        - 路由 
        - 视图
            面试题:你的写的类都继承过哪些类?
            class View(object):
            
            class APIView(View):
            
            class GenericAPIView(views.APIView):
            
            class GenericViewSet(ViewSetMixin, generics.GenericAPIView)
            
            class ModelViewSet(mixins.CreateModelMixin,
                   mixins.RetrieveModelMixin,
                   mixins.UpdateModelMixin,
                   mixins.DestroyModelMixin,
                   mixins.ListModelMixin,
                   GenericViewSet):
        - 分页 
        - 解析器
        - 渲染器
        - 版本 

    
今日内容:
    - vue
    - restful api 
    
内容详细:
    1. 渲染器
       规定页面显示的效果(无用)
    2. 版本 
        原理:要了解
        使用:
            1. 添加配置
                REST_FRAMEWORK = {
                    
                    .... 
                    
                    'DEFAULT_VERSIONING_CLASS':'rest_framework.versioning.URLPathVersioning',
                    'ALLOWED_VERSIONS':['v1','v2'], # 允许的版本
                    'VERSION_PARAM':'version', # 参数
                    'DEFAULT_VERSION':'v1', # 默认版本
                    ....
                }

            2. 设置路由 
                
                s9luffycity/urls.py
                    urlpatterns = [
                        #url(r'^admin/', admin.site.urls),
                        url(r'^api/(?P<version>\w+)/', include('api.urls')),
                    ]
                
                api/urls.py 
                    urlpatterns = [
                        url(r'^course/$', course.CourseView.as_view()),
                    ]
            
            3. 获取版本 
                request.version 获取版本  
            
    
    3. vue+rest framework
        vue: 
            - 路由 + 组件 
            - axios发送ajax请求
            - that 
        api:
            - 跨域 
            
        补充:
            - 域名不同
            - 端口不同 
        cors:
            本质设置响应头
                    
                    # 允许你的域名来获取我的数据
                    response['Access-Control-Allow-Origin'] = "*"

                    # 允许你携带Content-Type请求头
                    response['Access-Control-Allow-Headers'] = "Content-Type"

                    # 允许你发送DELETE,PUT
                    response['Access-Control-Allow-Methods'] = "DELETE,PUT"
        
    
作业:
    1.创建两张表
        课程表:
             id    title    
             1    Python全栈
             2    Python周末
             3    Linux
        课程详细表:
            id     name        course_id
            1    Python基础      1
            2    Python进阶      1
            3    Python网络      1
            4    Python并发      1
            5    Python数据库      1
            6    Python前端      1

    2. 两个页面
        - 课程列表
        - 课程详细 

 

内容回顾:
    - restful 规范(10- django rest framework框架(10- 跨域
        - 为什么会有跨域?
        - 绕过浏览器同源策略就可以跨域。
            - jsonp
                动态创建script标签
                同源策略会阻止ajax请求;不阻止具有src属性的标签
                <script src='xxxx'></script>
            - cors
                设置响应头
            
今日内容:
    - vue 
    - api
    
    
    
内容详细:
    1. vue
        - 课程列表
        - 课程详细
        
        - 任务:    
            - 课程表 
                id   title  course_img   level(choices) 
            - 课程详细(one2one  课程 )
                id   why  推荐课程
            - 章节 
                id    name  
        - 功能:
            a. 课程列表显示图片
            
            b. 课程详细显示:
                - 为什么要学习这个课程
                - 所有推荐课程
                - 所有章节
                 
    2. api
        1. 查询所有的课程
            http://127.0.0.1:8000/api/v1/course/
            练习:level变中文
            
        2. 查询课程详细 
            http://127.0.0.1:8000/api/v1/course/1/
            - 路由 as_view 是否添加参数,取决于视图继承的类
            - 序列化
                - depth
                - source
                - 自定义method
            
            练习:显示该课程相关的所有章节
            
    this补充:
        题目1:
            var name = '景女神'

            function Foo(name,age){
                this.name = name;
                this.age = age;
                this.getName = function(){
                    console.log(this.name); # 文州
                    
                    (function(){
                        console.log(this.name); # 女神
                    })()
                    
                }
            }

            obj = new Foo('文州',19)
            obj.getName()

        题目2:
            var name = '景女神'

            function Foo(name,age){
                this.name = name;
                this.age = age;
                this.getName = function(){
                    console.log(this.name); # 文州
                    var that = this 
                    (function(){
                        console.log(that.name); # 文州
                    })()
                    
                }
            }

            obj = new Foo('文州',19)

            obj.getName()

        题目3:
            var name = '景女神'
            obj = {
                name:'文州',
                age: 19,
                getName:function(){
                    console.log(this.name); # 文州
                    var that = this 
                    (function(){
                        console.log(that.name); # 文州
                    })()
                }
            }
            obj.getName()

    
作业:
    1. 前后端流程
    2. 图片 
    3. CC视频账号
    4. git相关
        - 安装git软件
        - 注册github账号

 

django rest framework restful 规范

 

内容回顾:
    1. 你理解的Http协议?
        - 建立在tcp之上
        - 一次请求一次响应然后断开连接(无状态、短连接)
        - 请求和响应
            发送:请求头\r\n\r\n请求体
                  host:www.luffy.com\r\ncontent-type:application/json\r\n\r\n请求体
            响应:响应头\r\n\r\n响应体
                  ...
    2. django请求生命周期
        
    3. wsgi
        
    4. django中间件是什么?
        
    5. 使用中间件做过什么?
        - 内置
            - csrf
            - session
        - 自定义
            - 登录认证
            - 权限
            - cors
    6. 中间件中有多少个方法?
        5个
    
    7. FBV和CBV是什么?以及优缺点。
    
    8. rest api 
        
    9. django rest framework框架
        
    10. 视图常见的继承
        from rest_framework.views import APIView # *
        from rest_framework.generics import GenericAPIView
        from rest_framework.viewsets import GenericViewSet # as_view
        from rest_framework.viewsets import ModelViewSet # *
    
    11. 如何实现的访问频率控制?
        匿名用户:无法控制,因为用户可以换代理IP
            {
                192.168.1.1:[1521223123.232, 1521223122.232, 1521223121.232],
                192.168.1.2:[1521223123.232, 1521223122.232, 1521223121.232],
                192.168.1.3:[1521223123.232, 1521223122.232, 1521223121.232],
                192.168.1.4:[1521223123.232, 1521223122.232, 1521223121.232],
                192.168.1.5:[1521223123.232, 1521223122.232, 1521223121.232],
                192.168.1.6:[1521223123.232, 1521223122.232, 1521223121.232],
            }
        
        
        登录用户:如果有很多账号,也无法限制
            {
                alex:[1521223123.232, 1521223122.232, 1521223121.232],
                eric:[1521223123.232, 1521223122.232, 1521223121.232],
            }
        
        参考源码:from rest_framework.throttling import SimpleRateThrottle
        
    12. 序列化
        - source
        - method 
    
    
    
今日内容:
    1. 示例
        - 推荐课程
        - 用户登录
        - 拦截器
        
        
        VUE:
            - 课程列表:this.$axios + this 
            - 课程详细:this.$axios + this 
            - 用户登录:
                - this.$axios
                - this 
                - 跨域简单和复杂请求
                - vuex做全局变量
                - vuex-cookies 
            - 微职位 
                - 拦截器
                - 携带token 
            
            PS: api可以同一放在store中保存
            
        API:
            - 课程列表 
                - 序列化:source='get_level_display'
            - 课程详细:
                - 序列化:source='get_level_display'
                - 序列化:method
            - 用户登录 
                - update_or_create
            - 微职位 
                - 认证组件 
            
            关联组件:
                - 版本
                - 解析器
                - 渲染器
                - 序列化 
                - 认证组件 
                - 视图 
                - 路由 
            
            
    2. django组件:contenttype
        组件的作用:可以通过两个字段让表和N张表创建FK关系
        
        
        表结构:
            from django.db import models
            from django.contrib.contenttypes.models import ContentType

            from django.contrib.contenttypes.fields import GenericForeignKey, GenericRelation


            class DegreeCourse(models.Model):
                """学位课程"""
                name = models.CharField(max_length=128, unique=True)
                course_img = models.CharField(max_length=255, verbose_name="缩略图")
                brief = models.TextField(verbose_name="学位课程简介", )


            class Course(models.Model):
                """专题课程"""
                name = models.CharField(max_length=128, unique=True)
                course_img = models.CharField(max_length=255)

                # 不会在数据库生成列,只用于帮助你进行查询
                policy_list = GenericRelation("PricePolicy")


            class PricePolicy(models.Model):
                """价格与有课程效期表"""
                content_type = models.ForeignKey(ContentType)  # 关联course or degree_course
                object_id = models.PositiveIntegerField()

                #不会在数据库生成列,只用于帮助你进行添加和查询
                content_object = GenericForeignKey('content_type', 'object_id')


                valid_period_choices = (
                    (1, '1天'),
                    (3, '3天'),
                    (7, '1周'), (14, '2周'),
                    (30, '1个月'),
                    (60, '2个月'),
                    (90, '3个月'),
                    (180, '6个月'), (210, '12个月'),
                    (540, '18个月'), (720, '24个月'),
                )
                valid_period = models.SmallIntegerField(choices=valid_period_choices)
                price = models.FloatField()

        使用:
            # 1.在价格策略表中添加一条数据
            # models.PricePolicy.objects.create(
            #     valid_period=7,
            #     price=6.6,
            #     content_type=ContentType.objects.get(model='course'),
            #     object_id=1
            # )

            # models.PricePolicy.objects.create(
            #     valid_period=14,
            #     price=9.9,
            #     content_object=models.Course.objects.get(id=1)
            # )

            # 2. 根据某个价格策略对象,找到他对应的表和数据,如:管理课程名称
            # price = models.PricePolicy.objects.get(id=2)
            # print(price.content_object.name) # 自动帮你找到

            # 3.找到某个课程关联的所有价格策略
            # obj = models.Course.objects.get(id=1)
            # for item in obj.policy_list.all():
            #     print(item.id,item.valid_period,item.price)
            #
        
    3. 表结构 
内容回顾:
    1. 为什么会有跨域?
        浏览器具有同源策略所有才出现跨域。
        同源策略:
            - 开放:src
            - 禁止:ajax
        解决跨域:
            - jsonp,在客户端动态创建一个script标签
                1.客户端:创建一个 
                    <script src='http://www.jxntv.cn/data/jmd-jxtv2.html'></script>
                    <script>
                        function func(arg){
                            alert(arg);
                        }
                    </script>
                2.服务端:接收到请求并处理并返回值 "func('success')"
                    相当于:
                        <script>
                            func('success')
                        </script>
                        
                PS: jsonp只能发送GET请求
                
            - cors,设置响应响应响应响应响应头
                - 简单请求
                - 复杂请求
                    - options请求做预检
                    - PUT/POST....
                    
        在django中解决方案:
            - 中间件中设置响应头
            - django中的一个第三方组件:cors
                
        补充:
            jQuery Ajax:
                $.ajax({
                    ...
                })
            原生Ajax:XMLHttpRequest对象:
                var xhr = new XMLHttpRequest()
                
                xhr.onreadystatechange = function(){
                    if(xhr.readyState == 4){
                        // 已经接收到全部响应数据,执行以下操作
                        var data = xhr.responseText;
                        console.log(data);
                    }
                };
                
                xhr.open('POST', "/test/", true);
                
                // 设置请求头
                xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset-UTF-8');
                
                // 发送请求
                xhr.send('n1=1;n2=2;');
                
    2. restful 规范
    
    3. 你理解的http协议?    
    
    4. 常见请求头
        - Content-Type 
        - User-Agent
        - referer,可以做图片防盗链。
        - Host
        - cookies

    5. 常见的请求方法:
        - GET/POST/DELETE/PUT/PATCH/OPTIONS

    6. 常见的状态码:
        - 200
        - 301/302
        - 403/404
        - 500
        
    7. 序列化 
    
    8. ORM补充:
        a. 需求: 只取某n列
            queryset=[ {},{}]
            models.User.objects.all().values( 'id','name')
            
            queryset=[ (),()]
            models.User.objects.all().values_list( 'id','name')
            
            queryset=[ obj,obj]
            result = models.User.objects.all().only('id','name','age')    
            # result = models.User.objects.all().defer('id','name','age')    
            for item in reuslt:
                print(item.id,item.name,item.age)
        b. 需求: 打印所有用户姓名以及部门名称
            
            class depart:
                title = ....
            
            
            class User:
                name = ...
                dp = FK(depart)
                
            # select * from user 
            # result = models.User.objects.all()
            # for item in result:
            #     print(item.name)
            
            # select * from user left join depart on user.dp_id = depart.id 
            # result = models.User.objects.all().selected_related('dp')
            # for item in result:
                #print(item.name,item.dp.title )

今日内容:
    1. 路飞学城表结构
        - 课程
        - 深科技
        
    2. 支付宝支付
    
    
内容详细:
    1. 路飞学城表结构
        - 课程
            - 学位课(导师、奖学金、分模块、周期)
            - 专题课 (小柯,周期)
        - 深科技

    2. 支付宝支付 
        a. 去支付宝申请 
            - 正式:营业执照
            - 测试:沙箱测试环境
                    APPID:2016082500309412
                    买家:
                        nbjsag5718@sandbox.com
                        111111
                        111111
        b. 开发程序
            SDK
                - 官方
                - github
                    pay.py 
                    依赖:pip3 install pycryptodome
            
            公钥私钥:
                - 应用公钥
                    - 支付宝公钥
                - 应用私钥
                
内容回顾:
    1. Http协议?
        Http协议就是一个传输数据格式。
        
        我原来学习django框架,从socket服务端开始学起。
        自己创造了一个socket服务器来充当:网站。
        浏览器当socket客户端。
        更清楚的明白到底http协议是什么?
            - 请求头 请求头
            - 响应头 响应头
        
        一次请求响应后,断开连接。
    2. 常见请求头 
        
    3. 常见的请求体?
        Form表单提交:
            POST /index http1.1\r\nhost:www.luffycity.com...\r\n\r\nusername=alex&password=123&...
        Ajax请求:
            POST /index http1.1\r\nhost:www.luffycity.com...\r\n\r\nusername=alex&password=123&...
            POST /index http1.1\r\nhost:www.luffycity.com...\r\n\r\n{“username”:"alex","password":123}
            
        补充:django中获取请求体
            - request.POST 
            - request.body 
            
    4. django请求生命周期
        - wsgi, 他就是socket服务端,用于接收用户请求并将请求进行初次封装,然后将请求交给web框架(Flask、Django)
        - 中间件,帮助我们对请求进行校验或在请求对象中添加其他相关数据,例如:csrf、request.session 
        - 路由匹配 
        - 视图函数,在视图函数中进行业务逻辑的处理,可能涉及到:orm、templates => 渲染
        - 中间件,对响应的数据进行处理。
        - wsgi,将响应的内容发送给浏览器。
        
    5. 中间件
        - 5个方法 
        - 应用场景:
            - 登录认证,不再需要在每个函数中添加装饰器
            - 权限,当用户登录时候获取当前用户所有权限并放入session,然后再次访问其他页面,获取当前url并在session中进行匹配。如果没有匹配成功,则在中间件返回“无权访问”
            - 跨域,
                    - jsonp,动态创建一个script标签。
                    - cors,设置响应头
                    应用:本地开始前后端分离的时使用。
        
    6. ORM操作
        - only
        - defer
        - seleted_related
        - prefetch_related
    
        示例:
            class Depart(models.Model): 5个部门
                title = models.CharField(...)

            class User(models.Model):   10个用户
                name = models.CharField(...)
                email = models.CharField(...)
                dp = models.FK(Depart)

            1.以前的你:11次单表查询

                result = User.objects.all()
                for item in result:
                    print(item.name,item.dp.title)

            2. seleted_related,主动做连表查询(1次链表)

                result = User.objects.all().seleted_related('dp')
                for item in result:
                    print(item.name,item.dp.title)

                问题:如果链表多,性能越来越差。

            3. prefetch_related:2次单表查询
                # select * from user ;
                # 通过python代码获取:dp_id = [1,2]
                # select * from depart where id in dp_id
                result = User.objects.all().prefetch_related('dp')
                for item in result:
                    print(item.name,item.dp.title)

        
        赠送:
            数据量比较大,不会使用FK,允许出现数据冗余。
        
    7. django rest framework的作用?
        快速搭建基于restful规范的接口。
    
    8. 你理解的 restful 规范?
        restful是一个规范,规定API如何编写,通过他可以让我们api更加简洁可维护。
        如,最直观的:
            method:
                - get
                - post 
                - put 
                - delete 
            
            原来都是url中设置的。
        除此之外:
            - api
            - 版本
            - 名词
            - 条件
            - 状态码
            - 返回值
            - 错误信息
            - hypermedia link 
    
    9. django rest framework组件:
        
        - 访问频率控制原理:
            匿名:
                1.1.1.1:[时间,时间,时间,时间,]
            登录:
                user:[时间,时间,时间,时间,] 
            
            默认将访问记录放在缓存中:redis/memcached
        - 序列化
            from rest_framework.serializers import Serializer

            class XX(Serializer):
                pass
            ser =XX(queryset,many=True) # ListSerializer对象
            ser =XX(obj, many=False)    # XX对象
                
        - 列表生成式 
        
        - 根据字符串的形式,自动导入模块并使用反射找到模块中的类【参考:s9day108】。
    
    

今日内容:
    1. 深科技表结构
    2. git
    
    
内容详细:
    1. 深科技表结构(6表)
        

        # ######################## 深科技相关 ########################
        class ArticleSource(models.Model):
            """文章来源"""
            name = models.CharField(max_length=64, unique=True)

            class Meta:
                verbose_name_plural = "16. 文章来源"

            def __str__(self):
                return self.name

        class Article(models.Model):
            """文章资讯"""
            title = models.CharField(max_length=255, unique=True, db_index=True, verbose_name="标题")
            source = models.ForeignKey("ArticleSource", verbose_name="来源")
            article_type_choices = ((0, '资讯'), (1, '视频'))
            article_type = models.SmallIntegerField(choices=article_type_choices, default=0)
            brief = models.TextField(max_length=512, verbose_name="摘要")
            head_img = models.CharField(max_length=255)
            content = models.TextField(verbose_name="文章正文")
            pub_date = models.DateTimeField(verbose_name="上架日期")
            offline_date = models.DateTimeField(verbose_name="下架日期")
            status_choices = ((0, '在线'), (1, '下线'))
            status = models.SmallIntegerField(choices=status_choices, default=0, verbose_name="状态")
            order = models.SmallIntegerField(default=0, verbose_name="权重", help_text="文章想置顶,可以把数字调大,不要超过1000")
            vid = models.CharField(max_length=128, verbose_name="视频VID", help_text="文章类型是视频, 则需要添加视频VID", blank=True, null=True)
            comment_num = models.SmallIntegerField(default=0, verbose_name="评论数")
            agree_num = models.SmallIntegerField(default=0, verbose_name="点赞数")
            view_num = models.SmallIntegerField(default=0, verbose_name="观看数")
            collect_num = models.SmallIntegerField(default=0, verbose_name="收藏数")

            # tags = models.ManyToManyField("Tags", blank=True, verbose_name="标签")
            date = models.DateTimeField(auto_now_add=True, verbose_name="创建日期")

            position_choices = ((0, '信息流'), (1, 'banner大图'), (2, 'banner小图'))
            position = models.SmallIntegerField(choices=position_choices, default=0, verbose_name="位置")


            #comment = GenericRelation("Comment")

            class Meta:
                verbose_name_plural = "17. 文章"

            def __str__(self):
                return "%s-%s" % (self.source, self.title)

        class Collection(models.Model):
            """收藏"""
            content_type = models.ForeignKey(ContentType)
            object_id = models.PositiveIntegerField()
            content_object = GenericForeignKey('content_type', 'object_id')

            account = models.ForeignKey("Account")
            date = models.DateTimeField(auto_now_add=True)

            class Meta:
                unique_together = ('content_type', 'object_id', 'account')
                verbose_name_plural = "18. 通用收藏表"

        class Comment(models.Model):
            """通用的评论表"""
            content_type = models.ForeignKey(ContentType, blank=True, null=True, verbose_name="类型")
            object_id = models.PositiveIntegerField(blank=True, null=True)
            content_object = GenericForeignKey('content_type', 'object_id')

            p_node = models.ForeignKey("self", blank=True, null=True, verbose_name="父级评论")
            content = models.TextField(max_length=1024)
            account = models.ForeignKey("Account", verbose_name="会员名")
            disagree_number = models.IntegerField(default=0, verbose_name="")
            agree_number = models.IntegerField(default=0, verbose_name="赞同数")
            date = models.DateTimeField(auto_now_add=True)

            def __str__(self):
                return self.content

            class Meta:
                verbose_name_plural = "19. 通用评论表"

        class Account(models.Model):
            username = models.CharField("用户名", max_length=64, unique=True)
            password = models.CharField("密码", max_length=64)

        class UserAuthToken(models.Model):
            """
            用户Token表
            """
            user = models.OneToOneField(to="Account")
            token = models.CharField(max_length=64, unique=True)
    
    
    2. git 
        git是一个用于帮助用户实现版本控制的软件。
        
        命令:
            git init 
            
            git status             查看当前文件夹的状态。
            git add 文件名        对指定文件进行版本控制
            git add .            对指定文件夹下的所有文件及子目录进行版本控制
            git commit -m '详细的描述信息' 创建提交记录(版本)
            
            git log 
            git reflog 
            
            git reset --hard 提交记录(版本号)

 django rest framework restful 规范

django rest framework restful 规范

django rest framework restful 规范

django rest framework restful 规范