惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

腾讯CDC
The Cloudflare Blog
IT之家
IT之家
V
V2EX
雷峰网
雷峰网
MyScale Blog
MyScale Blog
P
Proofpoint News Feed
Stack Overflow Blog
Stack Overflow Blog
博客园 - Franky
Engineering at Meta
Engineering at Meta
S
SegmentFault 最新的问题
GbyAI
GbyAI
Microsoft Azure Blog
Microsoft Azure Blog
博客园 - 司徒正美
云风的 BLOG
云风的 BLOG
小众软件
小众软件
博客园 - 叶小钗
Blog — PlanetScale
Blog — PlanetScale
C
Check Point Blog
A
About on SuperTechFans
B
Blog
月光博客
月光博客
宝玉的分享
宝玉的分享
Last Week in AI
Last Week in AI

陈少文的网站

巨变与机遇的未来十年 Kubernetes 平台管理软件压力测试方案 使用镜像部署 Hexo 静态页面 终于等到你 - GitHub 镜像仓库服务(ghcr.io) 一起来学 Go --(6)Interface 一起来学 Go --(5)Goroutine 和 Channel 什么是函数式编程 如何在 Kubernetes 集群集成 Kata 柯里化与偏函数 使用 PyGithub 自动创建 Label 软件产品是团队能力的输出 Helm 2 、Helm 3 比较 IoT 变现 Kubernetes 中的 DNS 服务 国内的 Helm 镜像源 Harbor 使用自签证书支持 Https 访问 DevOps 工具链之 Prow 如何使用 kfctl 安装 Kubeflow VS Code 无法下载 Go 插件的工具包 工程师更应具有服务精神 你不知道的 Docker 使用技巧 使用 Docker 运行 Tensorflow 论中国 什么是左移 如何清空 Git 仓库全部历史记录 一禅小和尚 有风吹过厨房 时间的玫瑰 如何在 CentOS 安装 GPU 驱动 开发 Tips(19)
Django Restful 接口之 Tastypie
微信公众号 · 2017-06-14 · via 陈少文的网站

Please enable Javascript to view the contents

1. Restful

REST,是Representational State Transfer的缩写,表现层状态转化。Restful,是一种开发理念,万维网软件架构风格。

1.1 Restful特点

  • 抽象资源
    图片、文本、歌曲、视频都是一种资源实体,在网络上,被抽象为资源。在Restful中,JSON常被用作这些资源的载体,统一对外提供数据信息。
  • 统一接口
    对数据的增删改查,分别对应于不同的HTTP方法。
  • GET(SELECT):从服务器取出资源(一项或多项)。
  • POST(CREATE):在服务器新建一个资源。
  • PUT(UPDATE):在服务器更新资源(客户端提供完整资源数据)。
  • PATCH(UPDATE):在服务器更新资源(客户端提供需要修改的资源数据)。
  • DELETE(DELETE):从服务器删除资源。
  • HEAD:获取资源的元数据。
  • OPTIONS:获取信息,关于资源的哪些属性是客户端可以改变的。

1.2 Restful规则

  • API URL前缀。为了兼顾API的扩展性,建议API的URL前缀设置为 http://example.com/api/v1/
  • URL中只能有名词。比如资源名和参数,http://example.com/api/v1/user/?id=1
  • 操作使用HTTP头设置。常见的有五种HTTP方法,GET、POST、PUT、PATCH、DELETE ,还有两个不常见的动词,HEAD、OPTIONS。用法:
    • GET /zoos/:列出所有动物园
    • POST /zoos/:新建一个动物园
    • GET /zoos/ID/:获取某个指定动物园的信息
    • PUT /zoos/ID/:更新某个指定动物园的信息(提供该动物园的全部信息)
    • PATCH /zoos/ID/:更新某个指定动物园的信息(提供该动物园的部分信息)
    • DELETE /zoos/ID/:删除某个动物园
    • GET /zoos/ID/animals:列出某个指定动物园的所有动物
    • DELETE /zoos/ID/animals/ID/:删除某个指定动物园的指定动物
  • 过滤规则
  • ?limit=10:指定返回记录的数量
  • ?offset=10:指定返回记录的开始位置。
  • ?page=2&per_page=100:指定第几页,以及每页的记录数
  • ?sortby=name&order=asc:指定返回结果按照哪个属性排序,以及排序顺序
  • ?animal_type_id=1:指定筛选条件

2. Tastypie

2.1 简介

Tastypie是基于Django的Restful api开发框架。通过简单的配置,就能对外提供Restful 风格的接口。

2.2 安装配置

1
pip instal django-tastypie

settings.py配置

1
2
3
 INSTALLED_APPS = (
    'tastypie',
)
1
python manage.py syncdb

如果需要对接口的权限进行限制,Tastypie也提供相应的支持。

第一步,继承Authorization类实现MyAuthorization权限管理类。
需要实现的函数有:

  • def read_list(self, object_list, bundle)
  • def read_detail(self, objec_list, bundle)
  • def create_detail(self, object_list, bundle)
  • def update_list(self, object_list, bundle)
  • def update_detail(self, object_list, bundle)
  • def delete_list(self, object_list, bundle)
  • def delete_detail(self, object_list, bundle)

第二步,在Resource的Meta中,指定权限管理实例

1
2
class Meta(BaseMeta):
      authorization = MyAuthorization()

2.4 捆对象 Bundles

在定制Resource的过程中,不可避免的会使用捆对象,这是一个抽象的概念,代表了获取资源,或者写入资源过程中对单个资源的封装

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
class BucketObject(object):
    def __init__(self, initial=None):
        self.__dict__['_data'] = {}

        if hasattr(initial, 'items'):
            self.__dict__['_data'] = initial

    def __getattr__(self, name):
        return self._data.get(name, None)

    def __setattr__(self, name, value):
        self.__dict__['_data'][name] = value

    def to_dict(self):
        return self._data

这里的BucketObject,并不对应任何的Model,只是当做对资源的一次打包,可以是几个model的合集,也可以是接口访问后封装的数据。

2.5 ModelResource

ModelResource 是基于已有Model提供Restful API。

第一步,创建resource资源

reasource.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from tastypie.resources import ModelResource
from .models import QuickView
class QickViewResource(ModelResource):
    class Meta:
        # 定义查询范围
        queryset = QuickView.objects.all()
        # 定义资源名
        resource_name = 'QucikView'
        # 其他配置
        excludes = ['create_time', 'update_time']

第二步,配置url路由,注册接口

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
from tastypie.api import Api
from ci.api.resources import QickViewResource
# 创建API V1版本,URL形式为/api/v1/
api_v1 = Api(api_name='v1')
# 注册资源
api_v1.register(QickViewResource())
# 新增资源注册放在这里

urlpatterns = patterns('',
                      (r'^api/', include(api_v1.urls)),
                      )

第三步,开始使用

/api/v1/?format=json

查看api v1注册的全部资源,list_endpoint表示资源端点,schema提供的URL可以查看字段和使用规则。

1
2
3
4
5
6
{
  "QucikView": {
    "list_endpoint": "/api/v1/QucikView/",
    "schema": "/api/v1/QucikView/schema/"
  }
}

/api/v1/QucikView/schema/?format=json

给出了基本的操作权限,默认参数,返回对象的字段和字段提示等。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
    allowed_detail_http_methods: [
        "get",
        "post",
        "put",
        "delete",
        "patch"
    ],
    allowed_list_http_methods: [
        "get",
        "post",
        "put",
        "delete",
        "patch"
    ],
    default_format: "application/json",
    default_limit: 20,
    fields: {
        app_id: {
            blank: false,
            default: "No default provided.",
            help_text: "Unicode string data. Ex: "Hello World"",
            nullable: false,
            primary_key: false,
            readonly: false,
            type: "string",
            unique: false,
            verbose_name: "业务ID"
        }
}

/api/v1/QucikView/?format=json&limit=1

获取资源的QucikView的列表,如果有分页,tastypie还会给出提示连接

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
{
  "meta": {
    "limit": 1,
    "next": "/api/v1/QucikView/?offset=1&limit=1&format=json",
    "offset": 0,
    "previous": null,
    "total_count": 8
  },
  "objects": [
    {
      "app_id": "1",
      "create_time": "2017-06-12T11:42:30.071000",
      "data": "{sadknlsakbf}",
      "id": 1,
      "index": 0,
      "is_deleted": false,
      "pipeline_id": "2",
      "resource_uri": "/ci/api/v1/QucikView/1/"
    }
  ]
}

2.6 Resource

如果需要基于第三方接口,或者几个Model,或者非ORM的数据源,对外提供Restful的接口,ModelResource 可能并不适用。tastypie 提供了Resource 类来抽象这部分资源。

这里主要是理解,上面提到的 捆对象 Bundles 概念,写一个BucketObject类,将资源封装在其中。

reasource.py

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class BuildResource(Resource):
    buildNo = fields.CharField(attribute='buildNo')
    starter = fields.CharField(attribute='starter')
    duration = fields.CharField(attribute='duration')
    endTime = fields.CharField(attribute='endTime')
    csReleaseNote = fields.CharField(attribute='csReleaseNote')
    statusBuild = fields.CharField(attribute='statusBuild')
    totalBuildNum = fields.CharField(attribute='totalBuildNum')

    class Meta:
        resource_name = 'BuildList'
        allowed_methods = ['get']
        object_class = BucketObject
        authorization = Authorization()

    def obj_get_list(self, request=None, **kwargs):
        if not request:
            request = kwargs['bundle'].request
        return self.get_object_list(request)

    def get_object_list(self, request):
        results = []
        key_list = ("buildNo", "starter", "duration", "endTime", "csReleaseNote",
                    "statusBuild", "statusBuild", "totalBuildNum")
        new_obj = BucketObject()
        for key in key_list:
            # 这里调用第三方接口,或者取其他Model数据,填充BucketObject
            setattr(new_obj, key, key+"_vaule")
        results.append(new_obj)
        return results

url中的配置和ModelResource一样。这里仅仅实现了get的函数重载,如果对应其他操作,也需要重写相应的函数。一共有九个:

  • detail _uri _kwargs
  • get
  • object_list
  • obj _get _list
  • obj _get
  • obj _create
  • obj _update
  • obj _delete_list
  • obj _delete
  • rollback

3. 参考


微信公众号