使用DjangoRESTFramework开发RESTfulAPI:完整教程
使用 Django REST Framework 开发 RESTful API:完整教程
Django REST Framework (DRF) 是一个强大且灵活的工具包,用于构建 Web API。它构建在 Django 之上,提供了一套简化的工具和功能,可以让你快速、高效地创建符合 REST 架构风格的 API。本教程将带你逐步了解如何使用 DRF 开发 RESTful API,从安装配置到高级特性,涵盖了构建强大 API 所需的一切。
1. 准备工作:安装与配置
-
安装 Django 和 DRF:
bash
pip install django djangorestframework
pip install markdown # 用于支持API文档的可浏览性
pip install django-filter # 用于支持过滤 -
创建 Django 项目和应用:
bash
django-admin startproject myproject
cd myproject
python manage.py startapp myapp -
配置
settings.py
:在
myproject/settings.py
中,将'rest_framework'
添加到INSTALLED_APPS
:python
INSTALLED_APPS = [
# ... 其他已安装的应用 ...
'rest_framework',
'myapp', # 你的应用
]
你还可以在settings.py
中进行全局的 DRF 配置(可选):
python
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticated', # 默认需要认证
],
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', #分页
'PAGE_SIZE': 10 #分页数量
}
2. 定义模型 (Models)
在 myapp/models.py
中定义你的数据模型。例如,一个简单的 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()
isbn = models.CharField(max_length=20, unique=True)
def __str__(self):
return self.title
```
运行数据库迁移:
bash
python manage.py makemigrations
python manage.py migrate
3. 创建序列化器 (Serializers)
序列化器负责将模型实例(Python 对象)转换为 JSON 等数据格式,反之亦然。 在 myapp/serializers.py
中创建序列化器:
```python
from rest_framework import serializers
from .models import Book
class BookSerializer(serializers.ModelSerializer):
class Meta:
model = Book
fields = 'all' # 或者指定具体的字段:['id', 'title', 'author', ...]
# fields = ['id', 'title', 'author', 'publication_date', 'isbn']
```
4. 构建视图 (Views)
DRF 提供了多种视图类,从简单的 APIView
到高度抽象的 GenericViewSet
,可以满足不同复杂度的需求。
-
使用
APIView
(最基础):```python
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Book
from .serializers import BookSerializerclass BookList(APIView):
def get(self, request):
books = Book.objects.all()
serializer = BookSerializer(books, many=True) # many=True 表示序列化多个对象
return Response(serializer.data)def post(self, request): 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)
class BookDetail(APIView):
def get_object(self, pk):
try:
return Book.objects.get(pk=pk)
except Book.DoesNotExist:
raise status.HTTP_404_NOT_FOUNDdef get(self, request, pk): book = self.get_object(pk) serializer = BookSerializer(book) return Response(serializer.data) def put(self, request, pk): book = self.get_object(pk) 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) def delete(self, request, pk): book = self.get_object(pk) book.delete() return Response(status=status.HTTP_204_NO_CONTENT)
```
-
使用
GenericViewSet
(更简洁、推荐):```python
from rest_framework import viewsets, mixins
from .models import Book
from .serializers import BookSerializerclass BookViewSet(mixins.ListModelMixin,
mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
viewsets.GenericViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
或者更简洁的使用`ModelViewSet`
python
class BookViewSet(viewsets.ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
```
5. 配置 URL 路由
在 myapp/urls.py
中配置 URL 路由:
```python
from django.urls import path, include
from rest_framework import routers
from .views import BookList, BookDetail, BookViewSet # 导入你的视图
使用 APIView 的路由
urlpatterns = [
path('books/', BookList.as_view()),
path('books/
]
使用 ViewSet 的路由 (更简洁)
router = routers.DefaultRouter()
router.register(r'books', BookViewSet)
urlpatterns = [
path('', include(router.urls)),
]
```
最后,在 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
path('api-auth/', include('rest_framework.urls')) # 可选,用于在可浏览 API 中添加登录/登出
]
```
6. 测试 API
现在你可以启动开发服务器并测试你的 API 了:
bash
python manage.py runserver
- 使用浏览器或 Postman: 访问
http://127.0.0.1:8000/api/books/
查看书籍列表,以及其他你定义的 URL。 - 使用 DRF 的可浏览 API: DRF 提供了一个非常方便的可浏览 API 界面,你可以在浏览器中直接查看 API 文档、发送请求、查看响应。
7. 高级特性
-
认证 (Authentication): DRF 支持多种认证方式,如 Basic Authentication, Token Authentication, Session Authentication, JWT (JSON Web Token) 等。
```python
settings.py
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.TokenAuthentication', #使用token认证
'rest_framework.authentication.SessionAuthentication', # 也可以同时支持 Session 认证
],
# ... 其他配置 ...
}
生成token,可以在`views.py`中添加:
python
from rest_framework.authtoken.models import Token
from django.contrib.auth.models import User# 为每个用户创建Token. 你可以在用户注册成功后自动调用。 for user in User.objects.all(): Token.objects.get_or_create(user=user)
在请求时,在`headers`中添加:
Authorization: Token 9944b09199c62bcf9418ad846dd0e4bbdfc6ee4b
``` -
权限 (Permissions): 控制谁可以访问你的 API 的哪些部分。
```python
views.py
from rest_framework.permissions import IsAuthenticated, IsAdminUser, AllowAny
class BookViewSet(viewsets.ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
permission_classes = [IsAuthenticated] # 只有认证用户才能访问# 或者为不同的操作设置不同的权限 def get_permissions(self): if self.action == 'list': permission_classes = [AllowAny] # 列表允许所有人 else: permission_classes = [IsAdminUser] #其他操作需要管理员 return [permission() for permission in permission_classes]
```
-
限流 (Throttling): 防止 API 被滥用。
```python
settings.py
REST_FRAMEWORK = {
'DEFAULT_THROTTLE_CLASSES': [
'rest_framework.throttling.AnonRateThrottle', # 匿名用户限流
'rest_framework.throttling.UserRateThrottle' # 登录用户限流
],
'DEFAULT_THROTTLE_RATES': {
'anon': '10/day', # 匿名用户每天10次
'user': '100/day' # 登录用户每天100次
}
# ...
}
或者在`views.py`中
python
from rest_framework.throttling import UserRateThrottle, AnonRateThrottleclass BookViewSet(viewsets.ModelViewSet):
# ...
throttle_classes = [UserRateThrottle, AnonRateThrottle]
``` -
过滤 (Filtering): 允许客户端根据条件筛选数据。
```python
views.py
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import filtersclass BookViewSet(viewsets.ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
filterset_fields = ['author', 'publication_date'] # 允许按作者和出版日期过滤
search_fields = ['title', 'isbn'] # 允许搜索标题和 ISBN
ordering_fields = ['title', 'publication_date'] # 允许按标题和出版日期排序
请求示例:
/api/books/?author=Tolkien # 过滤作者
/api/books/?search=Hobbit # 搜索标题
/api/books/?ordering=-publication_date # 按出版日期降序排序
``` -
分页 (Pagination): 将大量数据分成多个页面返回。
```python
settings.py 已经配置了全局分页
views.py (如果需要自定义某个视图的分页)
from rest_framework.pagination import PageNumberPagination
class LargeResultsSetPagination(PageNumberPagination):
page_size = 1000
page_size_query_param = 'page_size'
max_page_size = 10000class BookViewSet(viewsets.ModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
pagination_class = LargeResultsSetPagination # 使用自定义分页
请求示例:
/api/books/?page=2 # 获取第 2 页
/api/books/?page=2&page_size=50 # 获取第 2 页,每页 50 条
``` -
版本控制(Versioning):
```python
# settings.py
REST_FRAMEWORK = {
'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.URLPathVersioning', #最常用的
# 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.NamespaceVersioning',
# 'DEFAULT_VERSIONING_CLASS': 'rest_framework.versioning.AcceptHeaderVersioning','ALLOWED_VERSIONS': ['v1', 'v2'], # 允许的版本 'VERSION_PARAM': 'version', # 版本参数名
}
```python
# urls.py (使用 URLPathVersioning)
urlpatterns = [
path('api/v1/books/', ...), # v1 版本的 URL
path('api/v2/books/', ...), # v2 版本的 URL
]python
# views.py (获取版本)
class BookViewSet(viewsets.ModelViewSet):
def list(self, request, *args, **kwargs):
version = request.version # 获取版本号
# ... 根据版本号做不同的处理 ...
8. 总结
本教程详细介绍了如何使用 Django REST Framework 开发 RESTful API。 从基本的模型、序列化器、视图和 URL 配置,到认证、权限、限流、过滤、分页等高级特性,都进行了全面的讲解。 通过学习本教程,你应该能够构建出功能强大、结构良好、易于维护的 API。 记住,DRF 是一个非常灵活的框架,你可以根据自己的需求进行定制和扩展。 始终参考官方文档以获取最新信息和更多高级用法。