本文于2018/05/05 翻译 原文地址。
首发于,转载请注明出处
Django Rest Framework - Blog API
Mar 12, 2018
在本教程中,我们将构建一个以Django Rest框架为特征的博客应用程序的API,该应用程序使用的是CRUD (Create-Read-Update-Delete)功能。
这是有帮助的,但不需要事先有Django的经验。如果你正在寻找一个初学者友好的Django学习指南,我已经写了一整本书, Django for Beginners。完整的源代码可以在Github上找到。
SPAs
现代web应用程序越来越多地构建为单页应用程序(SPAs),它具有明显的前端和后端。与其他web框架(如Ruby on Rails-SPAs)中传统的monolith方法不同,SPAS需要一个后端API,然后可以根据需要使用多个前端。当一个公司需要多个前端应用程序 移动web、iOS、android 来使用相同的数据库时,这种方法很有效。它也可以说是未来趋势,因为前端可以是任何一JavaScript快速开发框架,但是后端始终保持稳定。
缺点是需要更多的时间和代码来为项目创建单独的前端/后端。
基于rest的api
API(应用程序编程接口)为开发人员提供了与应用程序数据库交互的接口。API不只是让用户完全访问数据库,而是为各种功能设置规则、权限和端点:登录、登出、阅读博客列表、个人博客详细信息等等。
传统的构建web API的方法是通过REST (Representational State Transfer),这是一种很好的架构,用于网站之间如何相互通信。由于计算机通过web进行通信,这意味着使用HTTP协议来支持许多常用的请求方式,例如GET、PUT、POST和DELETE。
还有许多相关的状态码,它们指示请求是否成功(200)、重定向(301)、丢失(404)或更糟(500)。
JSON
需要注意的是,由于一个API正在与另一台计算机通信,所以共享的信息并不是标准web页面所要发送的信息。例如,当您的浏览器请求(例如,谷歌主页)时,它会发送HTTP请求并接收HTML、CSS、JavaScript、图像等的HTTP响应。
API是不同的。通常,我们只对数据库中的数据感兴趣。这些数据通常转换成JSON格式,以便有效地传输。该API还将有一系列定义良好的规则,用于如何通过REST架构与前端客户端交互。要注册一个新用户,前端框架需要访问一个API端点,例如,/ API /register。这个API端点包含特定的URL路由和它自己的权限集。
Setup
我们将在Django中构建一个博客应用程序的模型来开始这个教程。然后,我们可以添加Django Rest框架,将其转换为RESTful API。
首先在计算机上为我们的代码创建一个新的目录。我会把它放在一个叫做api的文件夹里,但是你可以把它放在任何地方。然后配置我们的项目。
$ cd ~/Desktop
$ mkdir blogapi && cd blogapi
$ pipenv install django
$ pipenv shell
(blogapi) $ django-admin startproject blog_project .
(blogapi) $ python manage.py startapp posts
我们使用PIpenv 来安装Django 并且激活本地系统。这个名字就像blogapi-XXX一样,“XXX”是随机的。为了简洁起见,我将它缩短为blogapi。然后我们创建一个名为blogapi的新Django项目,并且创建第一个Django app ‘posts’ 。因为我们添加了一个新的app,我们需要告诉Django。因此,请确保将posts添加到设置.py文件中的INSTALLED_APPS列表。
# blog_project/settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'posts',]
我们的数据库模型很简单。让我们创建四个字段:title、content、created_at和updated_at。
# posts/models.py
from django.db import models
class Post(models.Model):
title = models.CharField(max_length=50)
content = models.TextField()
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
def __str__(self):
return self.title
请注意,我们还定义了模型的str表示 这个model应该是什么。Django里推荐这样做。
现在,首先创建一个新的迁移文件,然后应用它来更新我们的数据库。
(blogapi) $ python manage.py makemigrations
(blogapi) $ python manage.py migrate
好!我们希望在Django的后台中管理我们的数据,因此,让我们将Post添加到下面。
# posts/admin.py
from django.contrib import admin
from . models import Post
admin.site.register(Post)
然后创建一个超级用户帐户。
(blogapi) $ python manage.py createsuperuser
键入下面的命令并输入所有提示。
(blogapi) $ python manage.py createsuperuser
现在我们就可以启动web服务了
(blogapi) $ python manage.py runserver
浏览器输入 localhost:8000/admin。并使用刚刚创建的账户登陆。
点击帖子旁边的“+ Add”按钮,输入一些新的内容。
我已经创建了三个新的博客文章,您可以在这里看到。
我们已经完成了Django部分!由于我们正在创建一个API,所以我们不需要创建模板和视图。相反,现在是添加Django Rest框架来处理将模型数据转换为API的时候了。
Django Rest Framework
DRF负责将数据库模型转换为RESTful API。这个过程有两个主要步骤:首先通过序列化器将数据转换成JSON,这样就可以通过internet发送数据,然后使用view来定义发送的数据。
我们来看一下。首先使用Control+c停止本地服务器,并使用Pipenv安装Django Rest框架。
(blogapi) $ pipenv install djangorestframework
然后将它添加到我们的settings.py文件的INSTALLED_APPS部分。
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'posts',]
我喜欢在第三方应用程序(如rest_framework)和我自己的应用程序(如posts)之间保留空格。
现在创建一个新的py文件。
(blogapi) $ touch posts/serializers.py
请记住,序列化器用于将我们的数据转换成JSON格式。如下图所示。
#posts/serializers.py
from rest_framework import serializersfrom . import models
class PostSerializer(serializers.ModelSerializer):
class Meta:
fields = ('id', 'title', 'content', 'created_at', 'updated_at',)
model = models.Post
在前两个文件中,我们从DRF和我们的模型导入序列化器。接下来,我们创建一个序列化器类并在其中创建一个元类(Meta)。fields字段控制数据库数据的类型。在本例中,我们将暴露所有字段,包括id,这是Django的主键,由Django自动添加到所有数据库记录。
接下来,我们需要创建view。正如Django有基于类的视图一样,DRF也有我们可以使用的通用视图。让我们添加一个列出所有博客文章和一个特定职位的详细视图。
更新posts 文件夹下的view.py。
# posts/views.pyfrom rest_framework import generics
from . import modelsfrom . import serializers
class PostList(generics.ListAPIView):
queryset = models.Post.objects.all()
serializer_class = serializers.PostSerializer
class PostDetail(generics.RetrieveAPIView):
queryset = models.Post.objects.all()
serializer_class = serializers.PostSerializer
在顶部,我们从DRF中导入基础视图类generics,以及我们的模型和序列化文件。然后我们创建两个view :PostList和PostDetail。这两种方法都是用于GET,但是RetrieveAPIView仅用于模型的单个实例。通用视图的完整列表在DRF站点上。
最后一个是url。我们需要创建url路由——在api中称为端点——数据可用。
从根目录的urls.py文件开始。
# blog_project/urls.py
from django.contrib import admin
from django.urls import include, path
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('posts.urls')),]
我们已经添加了第2行导入,然后为我们的posts创建了一个名为api/的路径。接下来创建posts app的 urls.py文件。
(blogapi) $ touch posts/urls.py
然后输入下面的代码。
# posts/urls.py
from django.urls import path
from . import views
urlpatterns = [
path('', views.PostList.as_view()),
path('/', views.PostDetail.as_view()),]
所有的博客url都将在 api/里。所以我们的PostList将在api/里,postDetail 则在api/#里,其中#表示条目的id。例如,第一篇博客文章的id为1,所以它的路径为api/1, api/2则为第二篇文章,等等。
Browsable API
是时候查看我们的工作和查看一下DR的F杀手功能了。首先启动服务器。
(blogapi) $ python manage.py runserver
浏览器打开 http://127.0.0.1:8000 / api /
api/端点以JSON格式显示我的三个博客文章。
现在访问http://127.0.0.1:8000/api/1/,您将只看到第一个条目的数据。
Implementing CRUD
我在文章的开头就承诺,本教程不仅涵盖阅读/获取内容,还包括完整的CRUD语法。看看DRF是怎么轻易的就把我们的API转换成一个支持CRUD的API的。
打开posts/view.py 然后改变PostDetail 的参数列表为下图所示
# posts/views.py
class PostDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = models.Post.objects.all()
serializer_class = serializers.PostSerializer
现在刷新页面http://127.0.0.1:8000/api/1/,您可以在我们的图形用户界面中看到更新。
您可以使用“Delete”按钮来删除内容,“Put”来更新内容,“Get”可以像以前一样获取它。例如,导航到我们的第三个帖子的URL端点:http://127.0.0.1:8000/api/3/。然后,在页面底部使用图形界面来创建一条新数据。
你可以在做出改变后得到它:
Next Steps
我们只讲了DRF的基本用法。另一个受欢迎的特性是,与路由结合的ViewSets可以显著加快编写复杂的api。我也写了一个单独的帖子: DRF Serializers, Viewsets, and Routers.