如何利用 Django 进行 API 开发

时间:2022-10-26 12:16:09

如何利用 Django 进行 API 开发

Django REST Framework 与 Django Web 框架协同工作以创建 Web API。 我们不能仅使用 Django Rest Framework 来构建 Web API 。 在安装和配置 Django 本身之后,必须始终将其添加到项目中。

在本章中,我们将回顾传统 Django 和 Django REST Framework 之间的异同。 最重要的一点是,Django 创建的网站包含网页,而 Django REST Framework 创建的 Web API 是 URL 端点的集合,这些 URL 端点包含返回 JSON 的可用 HTTP 动词。

为了说明这些概念,我们将使用传统的 Django 建立一个基本的 Library 网站,然后使用 Django REST Framework 将其扩展为 Web API 。

Django 快速开发

首先,我们需要在计算机上有一个专用目录来存储代码。 它可以放置在任何地方,但为了方便起见,如果您使用的是 Mac,我们可以将其放在“桌面”文件夹中。

$ cd ~/Desktop
$ mkdir code && cd code

该代码文件夹将成为本书所有代码的位置。 下一步是为我们的库站点创建一个专用目录,通过 Pipenv 安装 Django ,然后使用 shell 命令进入虚拟环境。 您应该始终为每个新的 Python 项目使用专用的虚拟环境。

$ mkdir library && cd library
$ pipenv install django==2.2.6
$ pipenv shell
(library) $

Pipenv 在当前目录中创建一个 ​​Pipfile​​ 和一个 ​​Pipfile.lock​​ 。 命令行前括号中的(​​library​​)表明我们的虚拟环境处于活动状态。

传统的 Django 网站由一个项目 project 和一个(或多个)代表不同功能的应用 apps 组成。 让我们使用 startproject 命令创建一个新项目。 别忘了加上句号。 最后将代码安装在当前目录中。 如果不包括句点,则 Django 默认会创建一个附加目录。

(library)$ django-admin startproject library_project .

Django 会自动为我们生成一个新项目,我们可以使用 ​​tree​​ 命令看到它。 (注意:如果在 Mac 上无法使用 tree ,请使用 Homebrew :​​brew install tree​​ 安装。)

(library) $ tree .
├── Pipfile
├── Pipfile.lock
├── library_project
├── __init__.py
├── settings.py
├── urls.py
└── wsgi.py
└── manage.py

这些文件具有以下定义:

  • ​__init__.py​​ 是将目录视为软件包的 Python 方法; 它是空的
  • ​settings.py​​ 包含我们项目的所有配置
  • ​urls.py​​ 控制* URL 路由
  • ​wsgi.py​​ 代表 Web 服务器网关界面,可帮助 Django 服务于最终网页
  • ​manage.py​​ 执行各种 Django 命令,例如运行本地 Web 服务器或创建新应用。

运行 ​​migrate​​ 将数据库与 Django 的默认设置同步,然后启动本地 Django Web 服务器。

(library) $ python manage.py migrate
(library) $ python manage.py runserver

打开 Web 浏览器,访问 ​​http://127.0.0.1:8000/​​ 以确认我们的项目已成功安装。

如何利用 Django 进行 API 开发

第一个 app

典型的下一步是开始添加代表功能不同区域的应用程序。 一个 Django 项目可以支持多个应用程序。

通过键入 ​​Control + c​​ 停止本地服务器,然后创建一个 books 应用程序。

(library) $ python manage.py startapp books

现在再查看一下 Django 生成了什么文件。

.
├── Pipfile
├── Pipfile.lock
├── books
│ ├── __init__.py
│ ├── admin.py
│ ├── apps.py
│ ├── migrations
│ │ └── __init__.py
│ ├── models.py
│ ├── tests.py
│ └── views.py
├── db.sqlite3
├── library_project
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── wsgi.py
└── manage.py

每个应用程序都有一个 ​​__init__.py​​ 文件,将其标识为 Python 软件包。 创建了 6 个新文件:

  • ​admin.py​​ 是内置 Django Admin 应用程序的配置文件
  • ​apps.py​​ 是应用程序本身的配置文件
  • ​migrations/​​ 目录存储用于数据库更改的迁移文件
  • ​models.py​​ 是我们定义数据库模型的地方
  • ​tests.py​​ 用于我们的应用程序特定测试
  • ​views.py​​ 是我们处理 Web 应用程序的请求/响应逻辑的地方

通常,开发人员还会在每个应用程序内创建一个 ​​urls.py​​ 文件进行路由。

让我们构建文件,以便我们的图书馆项目列出首页上的所有书籍。 将您选择的文本编辑器打开到 ​​settings.py​​ 文件。 第一步是将新应用添加到我们的 INSTALLED_APPS 配置中。 我们总是在底部添加新应用,因为 Django 会按顺序读取它们,并且我们希望内置的核心 Django 应用(例如 admin 和 auth )在加载我们的应用之前已经被加载。

# library_project/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',

# Local
'books.apps.BooksConfig', # new
]

然后运行迁移以使我们的数据库与更改同步。

(library) $ python manage.py migrate

传统 Django 中的每个网页都需要多个文件:视图,URL 和模板。 但是首先我们需要一个数据库模型,所以让我们从这里开始。

Models

在您的文本编辑器中,打开文件 ​​book/models.py​​ 并进行如下更新:

# books/models.py
from django.db import models

class Book(models.Model):
title = models.CharField(max_length=250)
subtitle = models.CharField(max_length=250)
author = models.CharField(max_length=100)
isbn = models.CharField(max_length=13)

def __str__(self):
return self.title

这是一个基本的 Django 模型,我们在最上面一行从 Django 导入模型,然后创建一个扩展它的 Book 类。 有四个字段:标题,副标题,作者和 isbn 。 我们还包括 ​​__str__​​ 方法,以便稍后在管理员中显示书名。

请注意,ISBN 是分配给每本出版书籍的唯一的 13 个字符的标识符。

由于我们创建了一个新的数据库模型,因此我们需要创建一个迁移文件来进行处理。 指定应用名称是可选的,但建议在此处使用。 我们可以只键入 ​​python manage.py makemigrations​​,但是如果有多个应用程序进行了数据库更改,那么这两个应用程序都将被添加到迁移文件中,这使得将来的调试更加困难。 保持您的迁移文件尽可能具体。

然后运行迁移以更新我们的数据库。

(library) $ python manage.py makemigrations books 
(library) $ python manage.py migrate

到目前为止,一切都很好。

Admin

我们可以开始通过内置的 Django 应用将数据输入到我们的新模型中。 但是我们必须首先做两件事:

创建一个超级用户帐户并更新 ​​admin.py​​ ,以便显示 books 应用程序。从超级用户帐户开始。 在命令行上运行以下命令:

(library) $ python manage.py createsuperuser

按照提示输入用户名,电子邮件和密码。 请注意,出于安全原因,输入密码时屏幕上不会显示文本。

现在更新我们的图书应用的 ​​admin.py​​ 文件。

# books/admin.py
from django.contrib import admin
from .models import Book

admin.site.register(Book)

这就是我们所需要的! 再次启动本地服务器。

(library) $ python manage.py runserver

导航到 ​​http://127.0.0.1:8000/admin​​ 并登录。

如何利用 Django 进行 API 开发

您将被重定向到管理员主页。

如何利用 Django 进行 API 开发

单击书籍的链接。

如何利用 Django 进行 API 开发

然后点击右上角的“添加图书+”按钮。

如何利用 Django 进行 API 开发

我已经输入了 Django 初学者书籍的详细信息。 您可以在此处输入任何文本。 纯粹是出于演示目的。 单击“保存”按钮后,我们将重定向到列出所有当前条目的“书籍”页面。

如何利用 Django 进行 API 开发

我们传统的 Django 项目现在有数据,但是我们需要一种将其公开为网页的方法。 这意味着创建视图,URL 和模板文件。 现在开始吧。

Views

​views.py​​ 文件控制如何显示数据库模型内容。 由于我们要列出所有书籍,因此可以使用内置的通用类 ListView。更新 ​​books/views.py​​ 文件。

# books/views.py
from django.views.generic import ListView

from .models import Book

class BookListView(ListView):
model = Book
template_name = 'book_list.html'

首先,我们导入了 ListView 和 Book 模型。 然后,我们创建一个 BookListView 类,该类指定要使用的模型和模板(尚未创建)。

在拥有一个正常工作的网页之前,需要执行两个步骤:制作模板并配置 URL 。 让我们从 URL 开始。

URLs

我们需要同时设置项目级别的 ​​urls.py​​ 文件,然后在 books 应用程序中设置一个。 用户访问我们的网站时,他们将首先与 ​​library_project/urls.py​​ 文件进行交互,因此,请先对其进行配置。

# library_project/urls.py
from django.contrib import admin
from django.urls import path, include # new

urlpatterns = [
path('admin/', admin.site.urls),
path('', include('books.urls')), # new
]

前两行会导入内置的管理应用程序,路线的路径,并包括将与我们的图书应用程序一起使用的内容。 如果用户转到 ​​/admin/​​,他们将被重定向到 admin 应用。 我们在图书应用路由中使用空字符串 ​​' '​​,这意味着首页上的用户将直接重定向到图书应用。

现在,我们可以配置我们的 ​​books/urls.py​​ 文件。 但是,糟糕! Django 由于某种原因在应用程序中默认不包含 ​​urls.py​​ 文件,因此我们需要自己创建它。

(library) $ touch books/urls.py

现在,在文本编辑器中更新新文件。

# books/urls.py
from django.urls import path
from .views import BookListView

urlpatterns = [
path('', BookListView.as_view(), name='home'),
]

我们导入视图文件,在空字符串''处配置 BookListView ,并添加命名 URL 主页作为最佳实践。

Django 的工作方式,现在,当用户转到我们网站的主页时,他们将首先点击 ​​library_project/urls.py​​ 文件,然后将其重定向到使用 BookListView 指定的 ​​books/urls.py​​。 在此视图文件中,Book 模型与 ListView 一起使用以列出所有书籍。

最后一步是创建我们的模板文件,以控制实际网页上的布局。 我们已经在视图中将其名称指定为 ​​book_list.html​​。 其位置有两个选项:默认情况下,Django 模板加载器将在以下位置的 books 应用程序内查找模板:​​books/templates/books/book_list.html​​。 我们也可以改为创建一个单独的项目级模板目录,然后更新 ​​settings.py​​ 文件以指向该目录。

首先在 books 应用中创建一个新的模板文件夹,然后在其中创建一个 books 文件夹,最后是一个 ​​book_list.html​​ 文件。

(library) $ mkdir books/templates
(library) $ mkdir books/templates/books
(library) $ touch books/templates/books/book_list.html

然后更新 template 文件,

<!-- books/templates/books/book_list.html -->
<h1>All books</h1>
{% for book in object_list %}
<ul>
<li>Title: {{ book.title }}</li>
<li>Subtitle: {{ book.subtitle }}</li>
<li>Author: {{ book.author }}</li>
<li>ISBN: {{ book.isbn }}</li>
</ul>
{% endfor %}

Django 内置了允许基本逻辑的模板语言。 在这里,我们使用 for 标签来遍历所有可用的书。 模板标签必须包含在左/右括号和括号内。 因此,格式始终为 ​​{%for ...%}​​,然后我们必须稍后使用 ​​{%endfor%}​​ 关闭循环。

我们要遍历的是对象,其中包含 ListView 提供的所有可用书籍。 该对象的名称为 object_list 。 因此,为了遍历每本书,我们在 ​​{% for book in object_list %}​​。 然后显示模型中的每个字段。

网页

现在,我们可以启动本地 Django 服务器并查看我们的网页。

(library) $ python manage.py runserver

导航至位于 ​​http://127.0.0.1:8000/​​ 的主页。

如何利用 Django 进行 API 开发

如果我们在管理员中添加其他图书,则它们也都将出现在此处。

这是对传统 Django 网站的快速浏览。 现在,向其中添加一个 API !

Django REST 框架

就像其他任何第三方应用程序一样,添加了 ​​Django REST Framework​​。 如果本地服务器 ​​Control + c​​ 仍在运行,请确保退出它。 然后在命令行上键入以下内容。

(library) $ pipenv install djangorestframework==3.10.3

在我们的 ​​settings.py​​ 文件中,将 rest_framework 添加到 INSTALLED_APPS 配置中。 我喜欢在第三方应用程序和本地应用程序之间做出如下区分,因为在大多数项目中,应用程序的数量迅速增长。

最终,我们的 API 将公开一个端点,该端点列出 JSON 中的所有书籍。 因此,我们将需要一个新的 URL 路由,一个新的视图以及一个新的序列化器文件(稍后将对此进行更多介绍)。

我们可以用多种方法来组织这些文件,但是我的首选方法是创建一个专用的 api 应用程序。 这样,即使将来我们增加更多应用程序,每个应用程序都可以包含专用网页所需的模型,视图,模板和 url,但是整个项目的所有 API 专用文件都将驻留在专用 api 应用程序中。

让我们新建一个 ​​api​​ 应用程序。

(library) $ python manage.py startapp api

然后增加到 INSTALLED_APPS

# library_project/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',

# 3rd party
'rest_framework',

# Local Apps
'books.apps.BooksConfig',
'api.apps.ApiConfig', # new
]

api 应用程序将没有自己的数据库模型,因此无需像通常那样创建迁移文件和更新数据库。

URLs

从 URL 配置开始。 添加 API 端点就像配置传统 Django 应用的路由一样。 首先,在项目级别,我们需要包括 api 应用程序并配置其 URL 路由,即 ​​api/​​。

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
path('admin/', admin.site.urls),
path('', include('books.urls')),
path('api/', include('api.urls')), # new
]

然后在 api 应用程序中创建 ​​urls.py​​ 文件。

(library) $ touch api/urls.py

然后更新这个文件,如下:

# api/urls.py
from django.urls import path

from .views import BookAPIView

urlpatterns = [
path('', BookAPIView.as_view()),
]

一切准备就绪。

Views

接下来是我们的 ​​views.py​​ 文件,该文件依赖 Django REST Framework 的内置通用类视图。 这些是故意模仿传统 Django 基于类的通用视图的格式,但它们不是一回事。

为避免混淆,某些开发人员将调用 API 视图文件 ​​apiviews.py​​ 或 ​​api.py​​。 就个人而言,在专用的 api 应用程序中工作时,我发现仅调用 Django REST 框架视图文件 ​​views.py​​ 并不会造成混淆,但是在这一点上意见不一。

在我们的 ​​views.py​​ 文件中,将其更新为如下所示:

# api/views.py

from rest_framework import generics

from books.models import Book
from .serializers import BookSerializer

class BookAPIView(generics.ListAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer

在最上面的几行中,我们导入 Django REST Framework 的通用类视图,我们的 Books 应用中的模型以及 api 应用中的序列化器(我们将在下一个序列化器中导入)。

然后,我们创建一个 BookAPIView ,它使用 ListAPIView 为所有书籍实例创建一个只读端点。 有许多通用的视图,我们将在后面的章节中进一步探讨它们。

在我们的视图中,仅需执行两个步骤,即指定所有可用书籍的 queryset ,然后指定将成为 BookSerializer 的 ​​serializer_class​​。

Serializers

序列化器将数据转换为易于在 Internet 上使用的格式(通常为 JSON ),并显示在 API 端点上。 在接下来的章节中,我们还将更深入地介绍序列化器和 JSON 。 现在,我想演示使用 ​​Django REST Framework​​ 创建序列化器以将 Django 模型转换为 JSON 是多么容易。

在 api 应用中创建一个 ​​serializers.py​​ 文件:

(library) $ touch api/serializers.py

然后在文本编辑器中更新为如下所示:

# api/serializers.py
from rest_framework import serializers

from books.models import Book

class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = ('title', 'subtitle', 'author', 'isbn')

首先,我们从 Books 应用程序中导入 Django REST Framework 的序列化器类和 Book 模型。 我们将 Django REST Framework 的 ModelSerializer 扩展到 BookSerializer 类中,该类指定我们的数据库模型 Book 和我们希望公开的数据库字段:标题,副标题,作者和 isbn 。

大概就是这样! 完成了

cURL

我们想看看我们的 API 端点是什么样子。 我们知道它应该在 URL ​​http://127.0.0.1:8000/api/​​ 返回 JSON 。 确保我们的本地 Django 服务器正在运行:

(library) $ python manage.py runserver

现在打开一个新的第二个命令行控制台。 我们将使用它来访问在现有命令行控制台中运行的 API。

我们可以使用流行的 cURL 程序通过命令行执行 HTTP 请求。 我们需要一个基本的 GET 请求,以指定 ​​curl​​ 和我们要调用的 URL。


$ curl http://127.0.0.1:8000/api/
[
{
"title":"Django for Beginners",
"subtitle":"Build websites with Python and Django",
"author":"William S. Vincent",
"isbn":"978-198317266"
}
]

数据全部以 JSON 格式存在,但格式不正确且难以理解。 幸运的是,Django REST Framework 给我们带来了另一个惊喜:API 端点的强大可视模式。

Browsable API

在本地服务器仍在第一个命令行控制台中运行的情况下,在 Web 浏览器中的 ​​http://127.0.0.1:8000/api/​​ 上导航到我们的 API 端点。

如何利用 Django 进行 API 开发

哇,看看! Django REST Framework 默认情况下提供此可视化。 此页面中内置了许多功能,我们将在整本书中进行探讨。 现在,我希望您将此页面与原始 JSON 端点进行比较。 单击“获取”按钮,然后从下拉菜单中选择“ json”。

如何利用 Django 进行 API 开发

这就是来自 API 端点的原始 JSON 的样子。 我认为我们可以同意 Django REST Framework 版本更具吸引力。

总结

在本章中,我们讨论了很多内容,因此请不要担心现在是否会感到困惑。 首先,我们创建了一个传统的 Django 图书馆网站。 然后,我们添加了 Django REST Framework ,并能够以最少的代码添加 API 端点。