DjangoRESTFrameworkAPI开发:从零开始完整教程

Django REST Framework API 开发:从零开始完整教程

Django REST Framework (DRF) 是一个强大且灵活的工具包,用于构建 Web API。它基于 Django,提供了丰富的功能和简便的开发流程,使开发者能够快速高效地构建 RESTful API。本教程将带领你从零开始,一步步学习如何使用 DRF 开发 API,涵盖从环境搭建到高级特性的各个方面。

1. 环境准备

在开始之前,我们需要确保开发环境已准备就绪。这包括安装 Python、Django 和 DRF。

1.1 安装 Python

Django 和 DRF 都是基于 Python 的,所以首先需要安装 Python。建议使用 Python 3.8 或更高版本。你可以从 Python 官网下载并安装适合你操作系统的版本。

安装完成后,可以通过在终端或命令行中输入以下命令来验证安装是否成功:

bash
python --version

如果看到 Python 版本号,说明安装成功。

1.2 创建虚拟环境

强烈建议在虚拟环境中进行项目开发,以隔离项目依赖,避免不同项目之间的冲突。可以使用 venv 模块创建虚拟环境:

bash
python3 -m venv .venv

这将在当前目录下创建一个名为 .venv 的虚拟环境。

1.3 激活虚拟环境

在开始安装依赖之前,需要激活虚拟环境:

  • macOS/Linux:

bash
source .venv/bin/activate

  • Windows:

bash
.venv\Scripts\activate

激活虚拟环境后,你的终端提示符前会显示虚拟环境的名称(例如 (.venv))。

1.4 安装 Django 和 Django REST Framework

在激活的虚拟环境中,使用 pip 安装 Django 和 DRF:

bash
pip install django djangorestframework

你还可以安装一些常用的扩展包,例如:

  • markdown:支持 Markdown 格式的文档
  • django-filter:提供过滤功能

bash
pip install markdown django-filter

2. 创建 Django 项目和应用

2.1 创建 Django 项目

使用 django-admin 命令创建一个新的 Django 项目:

bash
django-admin startproject myproject .

myproject 替换为你想要的项目名称。. 表示在当前目录创建项目,这样可以避免多余的目录层级。

2.2 创建 Django 应用

Django 项目由一个或多个应用组成。使用 manage.py 文件创建一个新的应用:

bash
python manage.py startapp myapp

myapp 替换为你想要的应用名称。这将在项目目录下创建一个名为 myapp 的目录,其中包含应用的基本文件结构。

2.3 配置项目

接下来,需要对项目进行一些基本配置。

2.3.1 settings.py

打开 myproject/settings.py 文件,进行以下配置:

  • 添加应用到 INSTALLED_APPS:

将新创建的应用和 rest_framework 添加到 INSTALLED_APPS 列表中:

python
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'myapp', # 你的应用名称
]

  • 配置 REST_FRAMEWORK (可选):

你可以在 settings.py 中添加 REST_FRAMEWORK 配置项,自定义 DRF 的行为。例如,设置默认的渲染器、解析器、认证方式等。这里先使用默认配置,后续会根据需要进行调整。

2.3.2 urls.py

打开 myproject/urls.py 文件,添加应用的 URL 路由:

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

urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('myapp.urls')), # 添加应用的 URL 路由
]
```

这会将 /api/ 开头的请求路由到 myapp 应用的 URL 配置。

2.4 创建应用 URL 文件

myapp 目录下创建 urls.py 文件,用于定义应用的 URL 路由:

```python
from django.urls import path
from . import views

urlpatterns = [
# 在这里添加应用的 URL 路由
]
```

3. 构建数据模型

数据模型是 API 的基础,它定义了 API 操作的数据结构。在 myapp/models.py 文件中定义你的数据模型。

3.1 定义模型

例如,我们创建一个简单的 Book 模型,包含书名、作者和出版日期:

```python
from django.db import models

class Book(models.Model):
title = models.CharField(max_length=200)
author = models.CharField(max_length=100)
publication_date = models.DateField()

def __str__(self):
    return self.title

```

3.2 数据迁移

定义好模型后,需要进行数据迁移,将模型同步到数据库中。

首先,创建迁移文件:

bash
python manage.py makemigrations

然后,执行迁移:

bash
python manage.py migrate

这些命令会在数据库中创建对应的表。

4. 创建序列化器

序列化器负责将模型实例转换为 JSON 等数据格式,以及将接收到的数据反序列化为模型实例。在 myapp 目录下创建 serializers.py 文件。

4.1 定义序列化器

Book 模型创建一个序列化器:

```python
from rest_framework import serializers
from .models import Book

class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = 'all' # 或者指定需要的字段,例如:['id', 'title', 'author', 'publication_date']
```

这个序列化器会根据 Book 模型的字段自动生成序列化字段。

5. 创建视图

视图负责处理 API 请求,并返回响应。在 myapp/views.py 文件中定义视图。

5.1 基于函数的视图

我们可以先使用基于函数的视图来快速入门:

```python
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from .models import Book
from .serializers import BookSerializer

@api_view(['GET', 'POST'])
def book_list(request):
"""
列出所有书籍,或创建一本新书。
"""
if request.method == 'GET':
books = Book.objects.all()
serializer = BookSerializer(books, many=True)
return Response(serializer.data)

elif request.method == 'POST':
    serializer = BookSerializer(data=request.data)
    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

@api_view(['GET', 'PUT', 'DELETE'])
def book_detail(request, pk):
"""
检索、更新或删除一本书籍。
"""
try:
book = Book.objects.get(pk=pk)
except Book.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)

if request.method == 'GET':
    serializer = BookSerializer(book)
    return Response(serializer.data)

elif request.method == 'PUT':
    serializer = BookSerializer(book, data=request.data)
    if serializer.is_valid():
        serializer.save()
        return Response(serializer.data)
    return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

elif request.method == 'DELETE':
    book.delete()
    return Response(status=status.HTTP_204_NO_CONTENT)

```

这里定义了两个视图函数:

  • book_list:处理 /api/books/ 的 GET 和 POST 请求,分别用于获取所有书籍列表和创建新书。
  • book_detail:处理 /api/books/<pk>/ 的 GET、PUT 和 DELETE 请求,分别用于获取、更新和删除指定 ID 的书籍。

5.2 基于类的视图

虽然基于函数的视图简单易懂,但 DRF 更推荐使用基于类的视图,因为它们提供了更好的代码组织和重用性。

下面我们将上述基于函数的视图改写成基于类的视图:

```python
from rest_framework import generics
from .models import Book
from .serializers import BookSerializer

class BookList(generics.ListCreateAPIView):
"""
列出所有书籍,或创建一本新书。
"""
queryset = Book.objects.all()
serializer_class = BookSerializer

class BookDetail(generics.RetrieveUpdateDestroyAPIView):
"""
检索、更新或删除一本书籍。
"""
queryset = Book.objects.all()
serializer_class = BookSerializer
```

这里使用了 DRF 提供的通用视图类:

  • ListCreateAPIView:用于处理列表和创建操作。
  • RetrieveUpdateDestroyAPIView:用于处理检索、更新和删除操作。

这些通用视图类已经实现了常用的逻辑,我们只需要指定 querysetserializer_class 即可。

5.3 其他通用视图类

除了上述两个通用视图类,DRF 还提供了其他常用的通用视图类:

  • CreateAPIView:仅用于创建。
  • ListAPIView:仅用于列表。
  • RetrieveAPIView:仅用于检索。
  • DestroyAPIView:仅用于删除。
  • UpdateAPIView:仅用于更新。
  • RetrieveUpdateAPIView:用于检索和更新。

你可以根据需要选择合适的通用视图类。

6. 配置 URL

myapp/urls.py 文件中配置 URL 路由,将 URL 映射到视图:

```python
from django.urls import path
from . import views

urlpatterns = [
path('books/', views.BookList.as_view()),
path('books//', views.BookDetail.as_view()),
]
```

7. 测试 API

现在,我们可以启动开发服务器并测试 API 了。

7.1 启动开发服务器

bash
python manage.py runserver

这将启动 Django 开发服务器,默认监听 http://127.0.0.1:8000/

7.2 使用浏览器或 Postman 测试

你可以使用浏览器或 Postman 等工具来测试 API。

  • 浏览器:

    访问 http://127.0.0.1:8000/api/books/,你将看到书籍列表的 JSON 数据。由于我们使用了 ListCreateAPIView, DRF还会自动生成一个可以用来提交POST请求的表单。
    * Postman:

    你可以使用 Postman 发送 GET、POST、PUT、DELETE 等请求到不同的 API 端点,并查看响应结果。

例如:

  • GET http://127.0.0.1:8000/api/books/ 获取所有书籍列表。
  • POST http://127.0.0.1:8000/api/books/ 创建新书,需要在请求体中提供书籍数据。
  • GET http://127.0.0.1:8000/api/books/1/ 获取 ID 为 1 的书籍信息。
  • PUT http://127.0.0.1:8000/api/books/1/ 更新 ID 为 1 的书籍信息,需要在请求体中提供更新后的数据。
  • DELETE http://127.0.0.1:8000/api/books/1/ 删除 ID 为 1 的书籍。

8. 进阶功能

至此,我们已经构建了一个基本的 RESTful API。接下来,我们将介绍一些 DRF 的进阶功能,帮助你构建更强大、更完善的 API。

8.1 认证 (Authentication)

认证用于验证用户的身份。DRF 提供了多种认证方式,例如:

  • 基本认证 (BasicAuthentication): 使用用户名和密码进行认证。
  • 会话认证 (SessionAuthentication): 使用 Django 的会话系统进行认证。
  • 令牌认证 (TokenAuthentication): 使用令牌进行认证,通常用于 API 客户端。
  • JWT 认证 (JSON Web Token): 一种流行的令牌认证方式。

8.1.1 配置认证方式

settings.py 文件中配置 REST_FRAMEWORK

python
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
]
}

这将启用基本认证和会话认证。

8.1.2 添加Token认证

要使用 Token 认证,需要先在INSTALLED_APPS中添加 rest_framework.authtoken

python
INSTALLED_APPS = [
# ...
'rest_framework.authtoken',
# ...
]

然后执行数据迁移:

bash
python manage.py migrate

这将创建用于存储令牌的数据库表。

接着在REST_FRAMEWORK中添加:

python
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.BasicAuthentication',
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication', #新增Token认证
]
}

8.1.3 为用户生成Token

可以使用Django Admin后台为用户生成Token,或者通过代码生成:

```python
from rest_framework.authtoken.models import Token
from django.contrib.auth.models import User

user = User.objects.get(username='your_username') # 替换为你的用户名
token = Token.objects.create(user=user)
print(token.key)
```

8.1.4 在请求中使用Token

在请求头中添加 Authorization 字段,值为 Token 你的令牌

Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b

8.1.5 保护视图

你可以在视图类中添加 authentication_classes 属性,指定需要使用的认证方式:

```python
from rest_framework.authentication import SessionAuthentication, BasicAuthentication, TokenAuthentication
from rest_framework.permissions import IsAuthenticated

class BookList(generics.ListCreateAPIView):
queryset = Book.objects.all()
serializer_class = BookSerializer
authentication_classes = [SessionAuthentication, BasicAuthentication, TokenAuthentication]
permission_classes = [IsAuthenticated]
```

permission_classes 设置为 IsAuthenticated 表示只有通过认证的用户才能访问该视图。

8.2 权限 (Permissions)

权限用于控制用户对资源的访问权限。DRF 提供了多种权限类,例如:

  • AllowAny: 允许所有用户访问。
  • IsAuthenticated: 只允许认证用户访问。
  • IsAdminUser: 只允许管理员用户访问。
  • IsAuthenticatedOrReadOnly: 认证用户可以读写,匿名用户只能读取。

8.2.1 配置权限

你可以在 settings.py 中配置全局的权限类:

python
REST_FRAMEWORK = {
# ...
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated',
],
}

也可以在视图类中单独配置:

```python
from rest_framework.permissions import IsAuthenticated, AllowAny

class BookList(generics.ListCreateAPIView):
# ...
permission_classes = [IsAuthenticated] # 只有认证用户才能访问
# or
# permission_classes = [AllowAny] # 允许所有用户访问
# or
# permission_classes = [IsAuthenticatedOrReadOnly] # 认证用户可读写,匿名用户只读
```

8.3 限流 (Throttling)

限流用于限制 API 的访问频率,防止恶意攻击或滥用。DRF 提供了多种限流方式,例如:

  • AnonRateThrottle: 限制匿名用户的访问频率。
  • UserRateThrottle: 限制认证用户的访问频率。
  • ScopedRateThrottle: 根据不同的视图或操作设置不同的限流策略。

8.3.1 配置限流

settings.py 中配置 REST_FRAMEWORK

python
REST_FRAMEWORK = {
# ...
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle',
'rest_framework.throttling.UserRateThrottle'
],
'DEFAULT_THROTTLE_RATES': {
'anon': '100/day',
'user': '1000/day'
}
}

这将限制匿名用户每天最多访问 100 次,认证用户每天最多访问 1000 次。

你也可以在视图类中单独配置:

```python
from rest_framework.throttling import UserRateThrottle

class BookList(generics.ListCreateAPIView):
# ...
throttle_classes = [UserRateThrottle]
throttle_scope = 'books' # 设置限流作用域
```

然后在 settings.py 中配置 ScopedRateThrottle

python
REST_FRAMEWORK = {
# ...
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.ScopedRateThrottle',
],
'DEFAULT_THROTTLE_RATES': {
'books': '50/day', # 针对 books 作用域的限流策略
}
}

8.4 过滤 (Filtering)

过滤允许用户根据特定条件筛选数据。DRF 提供了强大的过滤功能。

8.4.1 使用 django-filter

首先,确保已安装 django-filter

bash
pip install django-filter

然后,在 settings.py 中将 django_filters 添加到 INSTALLED_APPS

python
INSTALLED_APPS = [
# ...
'django_filters',
# ...
]

并在 REST_FRAMEWORK 中添加 DjangoFilterBackend

python
REST_FRAMEWORK = {
# ...
'DEFAULT_FILTER_BACKENDS': [
'django_filters.rest_framework.DjangoFilterBackend'
],
}

8.4.2 在视图中配置过滤

在视图类中添加 filterset_fields 属性,指定可以过滤的字段:

```python
from django_filters.rest_framework import DjangoFilterBackend

class BookList(generics.ListCreateAPIView):
# ...
filter_backends = [DjangoFilterBackend]
filterset_fields = ['title', 'author'] # 允许按书名和作者过滤
```

现在,你可以通过 URL 参数进行过滤了:

  • http://127.0.0.1:8000/api/books/?title=Django:过滤出书名为 "Django" 的书籍。
  • http://127.0.0.1:8000/api/books/?author=John:过滤出作者为 "John" 的书籍。
  • http://127.0.0.1:8000/api/books/?title=Django&author=John:同时按书名和作者过滤。

8.4.3 自定义过滤器

django-filter 还支持创建自定义过滤器。

8.5 分页 (Pagination)

当 API 返回大量数据时,分页可以将数据分成多个页面,提高性能和用户体验。

8.5.1 配置分页

settings.py 中配置 REST_FRAMEWORK

python
REST_FRAMEWORK = {
# ...
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10 # 每页显示 10 条数据
}

这将启用分页功能,并设置每页显示 10 条数据。

8.5.2 分页响应

启用分页后,API 的响应会包含分页信息:

json
{
"count": 123,
"next": "http://api.example.org/accounts/?page=5",
"previous": "http://api.example.org/accounts/?page=3",
"results": [
{…},
{…},

]
}

  • count:总数据量。
  • next:下一页的 URL。
  • previous:上一页的 URL。
  • results:当前页的数据。

8.6 版本控制 (Versioning)

版本控制允许你同时维护 API 的多个版本,方便进行升级和维护。DRF 提供了多种版本控制方式,例如:

  • URL 路径版本控制: 在 URL 中包含版本号,例如 /api/v1/books/
  • 查询参数版本控制: 通过查询参数指定版本号,例如 /api/books/?version=1
  • 请求头版本控制: 在请求头中指定版本号。

8.6.1 配置版本控制

settings.py 中配置 REST_FRAMEWORK

python
REST_FRAMEWORK = {
# ...
'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning',
'ALLOWED_VERSIONS': ['v1', 'v2'], # 允许的版本号
'VERSION_PARAM': 'version' # 版本参数的名称
}

这将启用 URL 路径版本控制。

8.6.2 在 URL 中指定版本号

urls.py 中使用 namespace 指定版本号:

```python
from django.urls import path, include

urlpatterns = [
path('admin/', admin.site.urls),
path('api/v1/', include(('myapp.urls', 'myapp'), namespace='v1')),
path('api/v2/', include(('myapp.urls', 'myapp'), namespace='v2')),
]
```

然后在 myapp/urls.py 中添加版本相关的视图:

```python
from django.urls import path
from . import views

app_name = 'myapp' # 添加 app_name

urlpatterns = [
# v1版本的视图
path('books/', views.BookList.as_view(), name='book-list'),
path('books//', views.BookDetail.as_view(), name='book-detail'),
# 可以添加v2版本的视图,例如:
# path('v2/books/', views.BookListV2.as_view(), name='book-list-v2'),
]
```

现在,你可以通过不同的 URL 访问不同版本的 API:

  • /api/v1/books/:访问 v1 版本的书籍列表。
  • /api/v2/books/:访问 v2 版本的书籍列表。

8.7 文档 (Documentation)

良好的 API 文档可以帮助开发者更好地理解和使用 API。DRF 可以自动生成交互式的 API 文档。

8.7.1 使用 CoreAPI

CoreAPI 是一个文档生成工具,可以与 DRF 集成。

首先,安装 coreapipyyaml:

bash
pip install coreapi pyyaml

然后,在 settings.py 中将 coreapi 添加到 INSTALLED_APPS:

python
INSTALLED_APPS = [
# ...
'rest_framework_swagger',
# ...
]

并在 REST_FRAMEWORK 中添加 SchemaGenerator:

python
REST_FRAMEWORK = {
# ...
'DEFAULT_SCHEMA_CLASS': 'rest_framework.schemas.coreapi.AutoSchema'
}

8.7.2 使用 Swagger

Swagger 是一种流行的 API 文档工具,可以与 DRF 集成。

首先,安装 django-rest-swagger:

bash
pip install django-rest-swagger

然后,在 settings.py 中将 rest_framework_swagger 添加到 INSTALLED_APPS:

python
INSTALLED_APPS = [
# ...
'rest_framework_swagger',
# ...
]

8.7.3 配置 URL

myproject/urls.py 中添加 schema 视图的 URL:

```python
from rest_framework import permissions
from drf_yasg.views import get_schema_view
from drf_yasg import openapi

schema_view = get_schema_view(
openapi.Info(
title="Your API",
default_version='v1',
description="Your API description",
terms_of_service="https://www.google.com/policies/terms/",
contact=openapi.Contact(email="[email protected]"),
license=openapi.License(name="BSD License"),
),
public=True,
permission_classes=[permissions.AllowAny],
)

urlpatterns = [
# ...
path('swagger/', schema_view.without_ui(cache_timeout=0), name='schema-json'),
path('swagger/', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
path('redoc/', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
# ...
]
```

8.7.4 访问文档

现在,你可以访问以下 URL 查看 API 文档:

  • /swagger/:查看 Swagger UI 文档。
  • /redoc/:查看 ReDoc 文档。

这些文档是根据你的代码自动生成的,包含了 API 的所有端点、参数、请求体、响应体等信息。

9. 总结

本教程详细介绍了如何使用 Django REST Framework 从零开始构建 RESTful API,涵盖了环境准备、模型定义、序列化器、视图、URL 配置、测试、认证、权限、限流、过滤、分页、版本控制和文档等方面的内容。希望本教程能帮助你快速掌握 DRF 的核心概念和常用功能,并构建出强大、高效、易用的 Web API。

当然,DRF 还有更多高级特性和用法等待你去探索,例如自定义渲染器、解析器、认证方式、权限类、限流策略等。你可以参考 DRF 的官方文档深入学习:https://www.django-rest-framework.org/

希望你能在 API 开发的道路上越走越远,构建出更多优秀的 API 产品!

THE END