drf app

RESTful 十大规范

https://www.jianshu.com/p/a34f18d30aaa

二、十大规范
API与用户的通信协议,总是使用HTTPS协议

域名规范

https://api.example.com 尽量将API部署在专用域名(会存在跨域问题)
https://example.org/api/ API很简单(推荐)
版本规范

URL,如:https://api.example.com/v1/
请求头 跨域时,引发发送多次请求
路径,视网络上任何东西都是资源,均使用名词表示(可复数)

https://api.example.com/v1/zoos
https://api.example.com/v1/animals
https://api.example.com/v1/employees
method

GET :从服务器取出资源(一项或多项)
POST :在服务器新建一个资源
PUT :在服务器更新资源(客户端提供改变后的完整资源)
PATCH :在服务器更新资源(客户端提供改变的属性)
DELETE :从服务器删除资源
过滤,通过在url上传参的形式传递搜索条件

https://api.example.com/v1/zoos?limit=10:指定返回记录的数量
https://api.example.com/v1/zoos?offset=10:指定返回记录的开始位置
https://api.example.com/v1/zoos?page=2&per_page=100:指定第几页,以及每页的记录数
https://api.example.com/v1/zoos?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序
https://api.example.com/v1/zoos?animal_type_id=1:指定筛选条件
状态码

OK - [GET]:服务器成功返回用户请求的数据,该操作是幂等的(Idempotent)。
CREATED - [POST/PUT/PATCH]:用户新建或修改数据成功。
Accepted - [*]:表示一个请求已经进入后台排队(异步任务)
NO CONTENT - [DELETE]:用户删除数据成功。
INVALID REQUEST - [POST/PUT/PATCH]:用户发出的请求有错误,服务器没有进行新建或修改数据的操作,该操作是幂等的。
Unauthorized - [*]:表示用户没有权限(令牌、用户名、密码错误)。
Forbidden - [*] 表示用户得到授权(与401错误相对),但是访问是被禁止的。
NOT FOUND - [*]:用户发出的请求针对的是不存在的记录,服务器没有进行操作,该操作是幂等的。
Not Acceptable - [GET]:用户请求的格式不可得(比如用户请求JSON格式,但是只有XML格式)。
Gone -[GET]:用户请求的资源被永久删除,且不会再得到的。
Unprocesable entity - [POST/PUT/PATCH] 当创建一个对象时,发生一个验证错误。
INTERNAL SERVER ERROR - [*]:服务器发生错误,用户将无法判断发出的请求是否成功。

更多看这里:http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
错误处理,应返回错误信息,error当做key。
{
    'status':状态码,
    'error':错误信息,
}
返回结果,针对不同操作,服务器向用户返回的结果应该符合以下规范。

GET /collection:返回资源对象的列表(数组)
GET /collection/resource:返回单个资源对象
POST /collection:返回新生成的资源对象
PUT /collection/resource:返回完整的资源对象
PATCH /collection/resource:返回完整的资源对象
DELETE /collection/resource:返回一个空文档
Hypermedia API,RESTful API最好做到Hypermedia,即返回结果中提供链接,连向其他API方法,使得用户不查文档,也知道下一步应该做什么。
{"link": {
  "url": "路由"
  "rel":   "collection https://www.example.com/zoos",
  "href":  "https://api.example.com/zoos",
  "title": "List of zoos",
  "type":  "application/vnd.yourformat+json"
}}
三、在django中简单实现
前台通过发送不同的请求,进入不同的函数属性
class Book(APIView):

    def get(self, request):
        book_list = models.Books.objects.all()
        return render(request, 'books.html', locals())

    def put(self, request, pk):
        name = request.data.get('name')
        price = request.data.get('price')
        date = request.data.get('date')
        models.Books.objects.filter(pk=pk).update(name=name, price=price, create_date=date)
        return JsonResponse({'status': 100, 'msg': '成功'})

    def post(self, request):
        name = request.data.get('name')
        price = request.data.get('price')
        date = request.data.get('date')
        if name and price and date:
            models.Books.objects.create(name=name, price=price, create_date=date)
            return JsonResponse({'status': 100, 'msg': '成功'})
        else:
            return JsonResponse({'status': 200, 'msg': '失败'})

    def delete(self, request, pk):
        models.Books.objects.filter(pk=pk).delete()
        return JsonResponse({'status': 100, 'msg': '成功'})
码云源码链接

安装djangorestframework模块
方式一:pip3 install djangorestframework

方式二:pycharm图形化界面安装

方式三:pycharm命令行下安装(装在当前工程所用的解释器下)
。

谈谈你对restfull 规范的认识?

restful其实就是一套编写接口的'协议',规定如何编写以及如何设置返回值、状态码等信息。
# 最显著的特点:
# 用restful: 
    给用户一个url,根据method不同在后端做不同的处理
    比如:post创建数据、get获取数据、put和patch修改数据、delete删除数据。
# 不用restful: 
    给调用者很多url,每个url代表一个功能,比如:add_user/delte_user/edit_user/
# 当然,还有协议其他的,比如:
    '版本'来控制让程序有多个版本共存的情况,版本可以放在 url、请求头(accept/自定义)、GET参数
    '状态码'200/300/400/500
    'url中尽量使用名词'restful也可以称为“面向资源编程”
    'api标示'
        api.luffycity.com
        www.luffycity.com/api/

接口的幂等性是什么意思?

'一个接口通过1次相同的访问,再对该接口进行N次相同的访问时,对资源不造影响就认为接口具有幂等性。'
    GET,  #第一次获取结果、第二次也是获取结果对资源都不会造成影响,幂等。
    POST, #第一次新增数据,第二次也会再次新增,非幂等。
    PUT,  #第一次更新数据,第二次不会再次更新,幂等。
    PATCH,#第一次更新数据,第二次不会再次更新,非幂等。
    DELTE,#第一次删除数据,第二次不在再删除,幂等。

什么是RPC?

'远程过程调用协议'
是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。
进化的顺序: 现有的RPC,然后有的RESTful规范

为什么要使用django rest framework框架?

# 在编写接口时可以不使用django rest framework框架,
# 不使用:也可以做,可以用django的CBV来实现,开发者编写的代码会更多一些。
# 使用:内部帮助我们提供了很多方便的组件,我们通过配置就可以完成相应操作,如:
    '序列化'可以做用户请求数据校验+queryset对象的序列化称为json
    '解析器'获取用户请求数据request.data,会自动根据content-type请求头的不能对数据进行解析
    '分页'将从数据库获取到的数据在页面进行分页显示。
     # 还有其他组件:
         '认证'、'权限'、'访问频率控制 

django rest framework框架中都有那些组件?

#- 路由,自动帮助开发者快速为一个视图创建4个url
        www.oldboyedu.com/api/v1/student/$
        www.oldboyedu.com/api/v1/student(?P<format>\w+)$
        www.oldboyedu.com/api/v1/student/(?P<pk>\d+)/$
        www.oldboyedu.com/api/v1/student/(?P<pk>\d+)(?P<format>\w+)$
#- 版本处理
    - 问题:版本都可以放在那里?
            - url
            - GET 
            - 请求头 
#- 认证 
    - 问题:认证流程?
#- 权限 
    - 权限是否可以放在中间件中?以及为什么?
#- 访问频率的控制
    匿名用户可以真正的防止?无法做到真正的访问频率控制,只能把小白拒之门外。
    如果要封IP,使用防火墙来做。
    登录用户可以通过用户名作为唯一标示进行控制,如果有人注册很多账号,则无法防止。
#- 视图
#- 解析器 ,根据Content-Type请求头对请求体中的数据格式进行处理。request.data 
#- 分页
#- 序列化
    - 序列化
        - source
        - 定义方法
    - 请求数据格式校验
#- 渲染器 

django rest framework框架中的视图都可以继承哪些类

a. 继承APIView(最原始)但定制性比较强
    这个类属于rest framework中的顶层类,内部帮助我们实现了只是基本功能:认证、权限、频率控制,
但凡是数据库、分页等操作都需要手动去完成,比较原始。
    class GenericAPIView(APIView)
    def post(...):
          pass 

b.继承GenericViewSet(ViewSetMixin,generics.GenericAPIView)
  首先他的路由就发生变化
    如果继承它之后,路由中的as_view需要填写对应关系
  在内部也帮助我们提供了一些方便的方法:
  get_queryset
  get_object
  get_serializer
  get_serializer_class
  get_serializer_context
  filter_queryset
注意:要设置queryset字段,否则会抛出断言的异常。

代码
只提供增加功能 只继承GenericViewSet

class TestView(GenericViewSet):
  serialazer_class = xxx
  def creat(self,*args,**kwargs):
    pass  # 获取数据并对数据

c. 继承  modelviewset  --> 快速快发
    -ModelViewSet(增删改查全有+数据库操作)
    -mixins.CreateModelMixin(只有增),GenericViewSet
    -mixins.CreateModelMixin,DestroyModelMixin,GenericViewSet
  对数据库和分页等操作不用我们在编写,只需要继承相关类即可。
  
示例:只提供增加功能
class TestView(mixins.CreateModelMixin,GenericViewSet):
    serializer_class = XXXXXXX
*** 
  modelviewset --> 快速开发,复杂点的genericview、apiview

简述 django rest framework框架的认证流程。

- 如何编写?写类并实现authenticators
  请求进来认证需要编写一个类,类里面有一个authenticators方法,我们可以自定义这个方法,可以定制3类返回值。
  成功返回元组,返回none为匿名用户,抛出异常为认证失败。

源码流程:请求进来先走dispatch方法,然后封装的request对象会执行user方法,由user触发authenticators认证流程
- 方法中可以定义三种返回值:
    - (user,auth),认证成功
    - None , 匿名用户
    - 异常 ,认证失败
- 流程:
    - dispatch 
    - 再去request中进行认证处理

django rest framework如何实现的用户访问频率控制?

# 对匿名用户,根据用户IP或代理IP作为标识进行记录,为每个用户在redis中建一个列表
    {
        throttle_1.1.1.1:[1526868876.497521,152686885.497521...],
        throttle_1.1.1.2:[1526868876.497521,152686885.497521...],
        throttle_1.1.1.3:[1526868876.497521,152686885.497521...],
    } 
 每个用户再来访问时,需先去记录中剔除过期记录,再根据列表的长度判断是否可以继续访问。
 '如何封IP':在防火墙中进行设置
--------------------------------------------------------------------------
# 对注册用户,根据用户名或邮箱进行判断。
    {
        throttle_xxxx1:[1526868876.497521,152686885.497521...],
        throttle_xxxx2:[1526868876.497521,152686885.497521...],
        throttle_xxxx3:[1526868876.497521,152686885.497521...],
    }
每个用户再来访问时,需先去记录中剔除过期记录,再根据列表的长度判断是否可以继续访问。
\如1分钟:40次,列表长度限制在40,超过40则不可访问

drf app

上一篇:JS apply() call() bind()方法的使用


下一篇:vue + axios 图片上传