使用 Django REST Framework 前你必须要先了解的一些基本概念

1,696 阅读6分钟

前言

不同的框架都有不同的设计思想,因此在使用上会有很大的区别。在开始使用 Django REST Framework 框架之前,有一些你必须要了解的基本概念 🧠,了解他们有助于你更快上手 Django REST Framework 框架。


准备了一个 🐧 群,可加 537131912

关于 Django 和 Django REST Framework 的关系

首先这两个框架并不是一个团队或者说组织开发的,当然作为开源架构,肯定是有人同时参与了这两个框架开发。Django 诞生于 2010 年,而 Django REST Framework 诞生于 2011 年

Django 是老大哥 , Django REST Framework 是配合 Django 来开发接口的子框架。Django 可以独立完成一个项目的全部开发,但是 Django REST Framework 不行,它支持 Django 的一个补充,需要搭配 Django 才能使用。

首先需要明确的是 Django REST Framework 能做到事情,使用 Django 也可以做到,并没有只要 Django REST Framework 能做而 Django 做不了的事情。

但是使用 Django REST Framework 可以帮助我们用更少的代码完成相同的任务。更少的代码量意味着更少的 BUG 、更少的加班时间。不仅仅如此,更少的代码量意味着代码复用程度更高,以后修改起来就不会顾此失彼。

Django REST Framework 在后端开发中的角色

Django REST Framework 适用于开发 API 的,也就是你使用 HTTP 方法去请求它,它会返回 JSON 文本。

  • 如果你不知道什么是 API ,请谷歌一下 👍

  • 返回 JSON 文本并不意味着只能返回 JSON 文本,返回图片、视频等等也就算作 API 接口返回内容的范围。狭义上返回 JSON 文本,广义上返回 JSON、图片和视频等

说到这里你应该对 Django REST Framework 有一个基本概念了吧,首先 Django REST Framework 不能单独工作,而是作为 Django 的子框架存在。有一个通用办法,凡是 django 开头的库都是配合 Django 使用的,而不能单独使用,例如 django-filter

如何安装和使用 Django REST Framework

安装

安装 Django REST Framework

pip install djangorestframework
pip install markdown       # Markdown support for the browsable API.
pip install django-filter  # Filtering support

Django REST Framework 对应的 Python 库名字为 djangorestframework,全是小写字母且没有空格等其他分隔符。

除了安装 djangorestframework 本体之外,还推荐你安装 markdowndjango-filter,至于它俩是干嘛用的 ❓,以后你会知道的。

使用

这里只介绍最基本的两个概念,导包和导包之后怎么使用

导包

from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet, GenericViewSet

导包的语法就是 from rest_framework import something

嵌入 Django

前面说过 Django REST Framework 不是单独使用的,必须配合 Django 使用,需要在 Django 项目的 settings.py 文件中的 INSTALLED_APPS 属性中加入 'rest_framework',这样就可以在 Django 项目中愉快的使用 Django REST Framework 了。

INSTALLED_APPS = [
    'django.contrib.admin',
    'django.contrib.auth',
    'django.contrib.contenttypes',
    'django.contrib.sessions',
    'django.contrib.messages',
    'django.contrib.staticfiles',
    'rest_framework',
]

关于 MVT 和 MVVM 架构

Django 的架构叫做 MVT,而 Django REST Framework 的架构叫做 MVVM

  • MVT ( Model、View、Template )

  • MVVM( Model-View-ViewModel )

这个概念本身没有什么意思,对于初学者来说,知道了毫无意义,或者等你变为大神之后再去了解不迟,这里就稍微提一下。

关于序列化和反序列化

序列化和反序列化是 Django REST Framework 最重要的内容之一,那么什么是序列化和反序列化 ❓ 来介绍一下这两个概念。👇

什么是序列化

序列化就是像 Python 对象转为 JSON 文本的过程。了解 Python 的同学都知道 Python 中有很多个序列化类型,例如列表、元组和字符串等等,但是这里的序列化并不是将 XXX 东西转成 Python 的这些序列化类型哦,恰恰相反是将这些序列化类型转成 JSON 文本 。🤣

什么是反序列化

反序列化就是把序列化反过来,怎么反呢 ? 把 JSON 文本转成 Python 对象

为什么要在 Django REST Framework 引入序列化的概念

TODO

序列化和序列化中的 Python 对象其实就是字典和列表,以及包含在字典和列表中的数字和字符串,无他尔!为何?因为 JSON 的文本格式就是长得这样。

APIView 和 ViewSet 之间的关系和选择

Django 的视图有两种 Function base views ( FBV )Class base views ( CBV )FBV 基于函数的视图,CBV 基于类的视图。

Django REST FrameworkAPIView 就是对 DjangoCBV 进一步封装,而 ViewSet 就是对 APIView 的更进一步的封装。

具体封装了哪些内容,请看文章 TODO

from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet, GenericViewSet

上面是 APIViewViewSetrest_framework 库中的位置

从名字中就可以看出,一个是 views ,意味着一堆的 view;viewsets 含义是一堆 viewset,viewset 是什么呢?view 的集合!集合就是汇聚的意思,那到底汇聚了些啥东西?回忆上面那句话 “而 ViewSet 就是对 APIView 的更进一步的封装”,很明显就是把一堆的 APIView 聚合到了一起,( Python 的多继承),让我们开箱即用。懂了吗?不懂?简单说就是把一个一个的单个功能通过 Python 的多继承变成一个。

我们不直接使用 ViewSet,而是使用 ViewSet 的两个子类 ModelViewSet 和 GenericViewSet,关于这两个子类的方法会在下面介绍

说到这里,那 DjangoFBVDjango REST Framework 中充当了什么角色呢?

连视图这个概念都不知道的话,那你很不合格诶!!! 🤡

ModelViewSet, GenericViewSet 之间的关系和选择

TODO

使用 Django REST Framework 给路由带来的变化

ViewSet 方法和 HTTP 方法的对应关系

在文件 site-packages\rest_framework\routers.py 文件中表明了两者之间的对应关系。

TIPS:展示的只是部分代码,但是关键内容都在这里面了。

class SimpleRouter(BaseRouter):

    routes = [
        # List route.
        Route(
            url=r'^{prefix}{trailing_slash}$',
            mapping={
                'get': 'list',
                'post': 'create'
            },
            name='{basename}-list',
            detail=False,
            initkwargs={'suffix': 'List'}
        ),
        # Dynamically generated list routes. Generated using
        # @action(detail=False) decorator on methods of the viewset.
        DynamicRoute(
            url=r'^{prefix}/{url_path}{trailing_slash}$',
            name='{basename}-{url_name}',
            detail=False,
            initkwargs={}
        ),
        # Detail route.
        Route(
            url=r'^{prefix}/{lookup}{trailing_slash}$',
            mapping={
                'get': 'retrieve',
                'put': 'update',
                'patch': 'partial_update',
                'delete': 'destroy'
            },
            name='{basename}-detail',
            detail=True,
            initkwargs={'suffix': 'Instance'}
        ),
        # Dynamically generated detail routes. Generated using
        # @action(detail=True) decorator on methods of the viewset.
        DynamicRoute(
            url=r'^{prefix}/{lookup}/{url_path}{trailing_slash}$',
            name='{basename}-{url_name}',
            detail=True,
            initkwargs={}
        ),
    ]

SimpleRouter 类的 routes 类属性的各个成员的 mapping 表明了之间的映射关系,当然你大概率是看不懂这段代码的 🤡 ,不过我可以,让我来说给你听👇

routes 类属性是一个列表的成员是一堆 Route 类实例,至于 Route 类的源代码就不在这里展示了,不搭嘎。 Route 类的

warning:上面提到了一些 Python 中的概念,诸如 类、类实例、类属性、类方法等等,这个是基础知识中的基础知识中的基础知识中的基础知识中的基础知识中的基础知识中的基础知识中的基础知识中的基础知识中的基础知识中的基础知识中的基础知识中的基础知识中的基础知识 🤡 。

notice:下面的内容又涉及到 RESTful 规范的内容,你要不懂的话 🤡 ,嘿嘿,我也不想多赘述!

假设有这么一个 URL:/api/tweets/,并通过 TweetViewSet 视图类来绑定了这个接口

大致代码如下:

看不懂代码没关系,看文字描述就行了,看不懂文字描述也没关系,看个大概就好了

下面展示的都是对应文件中的关键位置代码,并不是全景展示

twitter/urls.py

router = routers.SimpleRouter()
router.register(r'api/users', UserViewSet)
router.register(r'api/accounts', AccountViewSet, basename='accounts')
router.register(r'api/tweets', TweetViewSet, basename='tweets')

我们使用 GET 请求去访问这个接口 ,

notice:在这里 URL /api/tweets/ 就是一个 API,为什么呢?因为它的名字里面的有 api 这三个字

warning:注意 Django 做的 URL 都要求以 / 结尾,不然会引发 302 重定向,浪费一次通讯