django rest framework restful 规范

 

内容回顾: 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帐号

 

 

内容回顾: 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 提交记录(版本号)