一、Django Rest Framework

Django REST Framework(简称DRF),是一个用于构建Web API的强大且灵活的工具包。

先说说REST:REST是一种Web API设计标准,是目前比较成熟的一套互联网应用程序的API设计理论。REST这个词,是Roy Thomas Fielding在他2000年的博士论文中提出的。Fielding是一个非常重要的人,他是HTTP协议(1.0版和1.1版)的主要设计者、Apache服务器软件的作者之一、Apache基金会的第一任主席。所以,他的这篇论文一经发表,就引起了关注,并且立即对互联网开发产生了深远的影响。

Fielding将他对互联网软件的架构原则,定名为REST,即Representational State Transfer的缩写。我对这个词组的翻译是”表现层状态转化”。如果一个架构符合REST原则,就称它为RESTful架构。所以简单来说,RESTful是一种Web API设计规范,根据产品需求需要定出一份方便前后端的规范,因此不是所有的标准要求都需要遵循。

学习RESTful API的资料:RESTful API 设计指南理解RESTful架构

你可能想要使用REST Framework的一些理由:

  • 基于Web可浏览的API能让你赢得更多开发者。
  • 包含OAuth1a和OAuth2的认证机制。
  • 序列化同时支持ORM和非ORM的数据源。
  • 自定义,如果不想用更为强大的功能,可以只使用常规的函数视图。
  • 大量的文档,牛叉的社区支持。
  • 得到大公司使用和信任,比如Mozilla、Red Hat、Eventbrite都用它,靠谱~。

二、安装需求

REST框架具有以下要求:

  • Python(2.7,3.2,3.3,3.4,3.5,3.6)
  • Django(1.10,1.11,2.0 alpha)

下面的包是可选的:

三、安装配置

1. 使用pip进行安装,包含那些你想要的可选包:

 

1

2

3

$ pip install djangorestframework

$ pip install markdown       # Markdown support for the browsable API.

$ pip install django-filter  # Filtering support

2. 添加rest_framework到settings.py的INSTALLED_APPS

 

1

2

3

4

INSTALLED_APPS = (

    ...

    'rest_framework',

)

3. (可选)如果想要增加可浏览的API,你也将需要添加REST框架的login和logout视图;添加如下行到根urls.py文件中。

 

1

2

3

4

urlpatterns = [

    ...

    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))

]

请注意,URL路径可以是任何你想要的,但你必须包括'rest_framework.urls''rest_framework'命名空间。你可以在Django 1.9+中省略命名空间,而REST框架将为你设置它。

四、使用示例

我们将创建一个简单的API来允许管理员用户查看和编辑系统中的用户和组。

创建一个名为的新Django项目tutorial,然后启动一个名为的新应用程序quickstart。

 

1

2

3

4

$ django-admin.py startproject tutorial

$ cd tutorial

$ django-admin.py startapp quickstart

$ cd ..

同步数据库,并且创建一个名为admin,密码为的初始用户password123。稍后在我们的示例中,我们将以用户身份进行身份验证。

 

1

2

3

$ python manage.py makemigrations

$ python manage.py migrate

$ python manage.py createsuperuser --username=admin [email protected]<br>

然后要完成djangoframework安装配置。

Serializers

首先我们要定义一些序列化器,创建一个名为tutorial/quickstart/serializers.py的文件,将用于定义如何展示API的新模块。

 

1

2

3

4

5

6

7

8

9

10

11

12

from django.contrib.auth.models import User, Group

from rest_framework import serializers

 

class UserSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:

        model = User

        fields = ('url', 'username', 'email', 'groups')

 

class GroupSerializer(serializers.HyperlinkedModelSerializer):

    class Meta:

        model = Group

        fields = ('url', 'name')

请注意,在这种情况下,我们使用超链接关系HyperlinkedModelSerializer(继承的类是HyperlinkedModelSerializer)。你也可以使用ModelSerializer继承,但超链接是一个很好的RESTful设计。

Views

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

from django.contrib.auth.models import User, Group

from rest_framework import viewsets

from tutorial.quickstart.serializers import UserSerializer, GroupSerializer

 

class UserViewSet(viewsets.ModelViewSet):

    """

    API endpoint that allows users to be viewed or edited.

    """

    queryset = User.objects.all().order_by('-date_joined')

    serializer_class = UserSerializer

 

class GroupViewSet(viewsets.ModelViewSet):

    """

    API endpoint that allows groups to be viewed or edited.

    """

    queryset = Group.objects.all()

    serializer_class = GroupSerializer

我们把所有常见的行为组合在一起,形成ViewSets视图集,而不是编写多个视图。如果需要的话,我们可以很容易地将这些视图分解成单独的视图,但是使用视图集使视图逻辑很好地组织,并且非常简洁。

URLs

最后可以编写URL,在tutorial/urls.py。

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

from django.conf.urls import url, include

from rest_framework import routers

from tutorial.quickstart import views

 

router = routers.DefaultRouter()

router.register(r'users', views.UserViewSet)

router.register(r'groups', views.GroupViewSet)

 

# Wire up our API using automatic URL routing.

# Additionally, we include login URLs for the browsable API.

urlpatterns = [

    url(r'^', include(router.urls)),

    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework'))

]

因为我们使用视图集而不是视图,所以我们可以自动为我们的API生成URL conf,只需向routers类注册视图集即可(可以给Default.Router添加trailing_slash,用来控制URL反斜杠的,默认为True,表示/users/跟/users效果一样;如果为False时/users/访问会报错)。

同样,如果我们需要对API URL进行更多的控制,我们可以直接使用普通的基于类的视图,并明确地写入URL conf。

另外当我们使用viewsets.ModelViewSet超类时可以没有base_name参数,但是使用viewsets.ViewSet超类就必须要使用base_name参数。

 

1

2

router = routers.DefaultRouter(trailing_slash=True)

router.register(r'users', UserViewSet, base_name='users')

Settings

最后,djangoframework将包括默认的登录和注销视图,以便使用可浏览的API,这是可选的;但如果你的API需要身份验证,并且你想使用可浏览的API,则可以使用它。比如希望我们的API只能被管理员用户访问,设置模块将处于tutorial/settings.py。

所有REST框架的全局设置都被保存到一个叫做REST_FRAMEWORK的配置字典中。

 

1

2

3

4

5

6

7

8

9

10

11

INSTALLED_APPS = (

    ...

    'rest_framework',

)

 

REST_FRAMEWORK = {

    'DEFAULT_PERMISSION_CLASSES': [

        'rest_framework.permissions.IsAdminUser',

    ],

    'PAGE_SIZE': 10

}

使用Django标准的’django.contrib.auth’权限,或者对未验证的用户使用只读权限。

 

1

2

3

4

5

REST_FRAMEWORK = {

    'DEFAULT_PERMISSION_CLASSES': [

        'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'

    ]

}

测试API

准备测试我们建立的API,从命令行启动服务器。

 

1

$ python manage.py runserver

现在可以在浏览器中输入http://127.0.0.1:8000/来打开API了。

【Python项目】CMDB的搭建05(Django REST framework)

并且可以查看所创建的全部’users’ API,直接点击url使用浏览器访问也行,或者使用postman工具。

或者使用curl或httpie来测试我们的API,Httpie是用Python编写的一个用户友好的http客户端,可以使用pip安装httpie。

 

1

2

$ pip install httpie

$ http http://127.0.0.1:8000/

使用curl命令,如下:

 

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

$ curl -H 'Accept: application/json; indent=4' -u admin:admin http://127.0.0.1:8000/users/

[

    {

        "url": "http://127.0.0.1:8000/users/1/",

        "username": "dkey",

        "email": "[email protected]",

        "is_staff": false

    },

    {

        "url": "http://127.0.0.1:8000/users/2/",

        "username": "admin",

        "email": "[email protected]",

        "is_staff": true

    }

]

如果你使用管理员登录(需要创建一个管理员用户),那么现在就应该可以添加、创建和删除用户了。

五、再说Serializers与Views

前面我们那个Serializers用的是HyperlinkedModelSerializer超链接管理,views很简单。下面是一个标准的djangoframework Serializers/views,Serializers继承ModelSerializers类,映射模型字段。这里给了一个样例:

Models.py

 

1

2

3

4

5

6

7

8

9

10

11

from django.db import models

 

class VirtualHost(models.Model):

 

    hostname = models.CharField(verbose_name='Hostname', max_length=30, blank=True, null=True)

    ip = models.GenericIPAddressField(verbose_name='IP', blank=True, null=True)

    cpu = models.CharField(verbose_name='Cpu', max_length=30, blank=True, null=True)

    memory = models.CharField(verbose_name='Memory', max_length=30, blank=True, null=True)

 

    class Meta:

        db_table = 'host'

serializers.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

from rest_framework.serializers import ModelSerializer

from rest_framework import serializers

from api.models import VirtualHost

 

 

class VirtualHostCreateSerializer(ModelSerializer):

 

    class Meta:

        model = VirtualHost

        fields = ('hostname', 'ip', 'cpu', 'memory')

 

 

class VirtualHostListSerializer(ModelSerializer):

 

    class Meta:

        model = VirtualHost

        fields = ('hostname', 'ip', 'cpu', 'memory')

 

 

class VirtualHostDetailSerializer(ModelSerializer):

 

    class Meta:

        model = VirtualHost

        fields = ('hostname', 'ip', 'cpu', 'memory')

views.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

31

32

33

34

35

36

37

38

39

from django.shortcuts import render

from rest_framework.viewsets import ModelViewSet

from rest_framework import viewsets

from rest_framework.response import Response

from rest_framework import status

from .serializers import *

from .models import VirtualHost

 

 

class VirtualHostViewSet(ModelViewSet):

    def create(self, request, *args, **kwargs):

        self.serializer_class = VirtualHostCreateSerializer

        data = request.data.dict()

        serial = VirtualHostCreateSerializer(data=data)

        if not serial.is_valid():

            return Response(status=status.HTTP_400_BAD_REQUEST)

 

        serial.save()

        return Response(serial.data)

 

    def destroy(self, request, *args, **kwargs):

        pass

 

    def update(self, request, *args, **kwargs):

        pass

 

    def list(self, request, *args, **kwargs):

        self.serializer_class = VirtualHostListSerializer

        self.queryset = VirtualHost.objects.all()

        return super(VirtualHostViewSet, self).list(request)

 

    def retrieve(self, request, *args, **kwargs):

        pk = kwargs.get('pk', 1)

        self.serializer_class = VirtualHostDetailSerializer

        self.queryset = VirtualHost.objects.filter(pk=pk)

        return super(VirtualHostViewSet, self).retrieve(request)

 

    def partial_update(self, request, *args, **kwargs):

        self.update(request, *args, **kwargs)

这里定义的create、destroy、update、list、retrieve方法都是djangoframework默认已经有的。并且不同的调用方式,djangoframework会使用不同的方法(我们这里定义就是重写这些方法,方法名称一定要一致),这些也是API常用的方法。所以我们在定义接口视图时,可能会有不同的业务逻辑,但是接口操作方式基本就这么几种了;根据自己的业务逻辑去重写这些方法即可。

另外也可以根据已有的方法添加新方法,比如partial_update方法,做部分更新使用的。继承了update方法。

六、官方教程

本教程将引导熟悉REST框架创建每一部分。学习它需要一些时间,但是它会让你对每一部分如何相互匹配在一起邮个全方位的了解,强烈建议读一下。

为了测试的目的,有一个完整的教程API的实例API,可以在这里找到

另外也可以看:

转载文章链接:

https://www.ywnds.com/?p=12148

相关文章:

  • 2022-01-06
  • 2021-09-21
  • 2022-01-26
  • 2022-01-12
  • 2022-12-23
  • 2021-12-23
  • 2021-10-23
猜你喜欢
  • 2021-08-07
  • 2021-04-06
  • 2022-02-21
  • 2022-12-23
  • 2021-07-10
  • 2021-08-15
  • 2021-11-01
相关资源
相似解决方案