Django REST Framework 教程 – wiki大全


Django REST Framework 教程:构建功能强大的Web API

在现代Web开发中,构建健壮、可扩展的API是不可或缺的。Django REST Framework (DRF) 是一个功能强大且灵活的工具包,它基于Django框架,使得构建Web API变得异常简单和高效。本教程将带你深入了解DRF的核心概念和实践,让你能够快速上手并构建自己的API。

1. 为什么选择 Django REST Framework?

Django 以其“包含电池”的理念而闻名,DRF则将这一理念带到了API开发领域。它提供了:
* 序列化器 (Serializers): 轻松地将Django模型实例序列化为JSON/XML等格式,并反序列化回模型实例。
* 视图 (Views): 提供了一系列通用视图和视图集,极大地简化了API视图的编写。
* 认证与权限 (Authentication & Permissions): 灵活的认证和权限系统,确保API的安全。
* 路由器 (Routers): 自动生成URL模式,减少手动配置的重复工作。
* 内置浏览器API (Browsable API): 提供了一个友好的Web界面,方便测试和调试API。
* 丰富的功能: 包含限流、过滤、分页等常用功能。

2. 环境搭建

首先,确保你已经安装了Django。然后,安装Django REST Framework:

bash
pip install djangorestframework
pip install markdown # 可选,用于Browsable API
pip install django-filter # 可选,用于过滤功能

在你的Django项目的 settings.py 中,将 rest_framework 添加到 INSTALLED_APPS

“`python

myproject/settings.py

INSTALLED_APPS = [
# …
‘rest_framework’,
# …
]

可选:配置DRF的全局设置

REST_FRAMEWORK = {
‘DEFAULT_PERMISSION_CLASSES’: [
‘rest_framework.permissions.IsAuthenticated’,
],
‘DEFAULT_AUTHENTICATION_CLASSES’: [
‘rest_framework.authentication.SessionAuthentication’,
‘rest_framework.authentication.BasicAuthentication’,
],
‘DEFAULT_PAGINATION_CLASS’: ‘rest_framework.pagination.PageNumberPagination’,
‘PAGE_SIZE’: 10,
‘DEFAULT_FILTER_BACKENDS’: [
‘django_filters.rest_framework.DjangoFilterBackend’,
]
}
“`

3. 创建第一个API:以博客文章为例

假设我们有一个简单的博客应用,其中包含 Post 模型。

3.1 定义模型 (models.py)

“`python

blog/models.py

from django.db import models
from django.contrib.auth.models import User

class Post(models.Model):
title = models.CharField(max_length=200)
content = models.TextField()
author = models.ForeignKey(User, on_delete=models.CASCADE)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)

def __str__(self):
    return self.title

“`

运行数据库迁移:
bash
python manage.py makemigrations
python manage.py migrate

3.2 序列化器 (serializers.py)

序列化器负责将Python对象(如Django模型实例)转换为可传输的格式(如JSON),反之亦然。

“`python

blog/serializers.py

from rest_framework import serializers
from .models import Post
from django.contrib.auth.models import User

class UserSerializer(serializers.ModelSerializer):
class Meta:
model = User
fields = [‘id’, ‘username’]

class PostSerializer(serializers.ModelSerializer):
author = UserSerializer(read_only=True) # 嵌套序列化器,用于显示作者信息

class Meta:
    model = Post
    fields = ['id', 'title', 'content', 'author', 'created_at', 'updated_at']
    # read_only_fields = ['author'] # 如果不希望通过API修改作者

“`

3.3 视图 (views.py)

DRF提供了多种视图选项:
* APIView: 最基本的视图,类似于Django的 View,需要手动处理请求和响应。
* GenericAPIView: 提供了通用行为,如 get_object()get_queryset(),常与其他Mixin配合使用。
* Mixin类: 如 ListModelMixinRetrieveModelMixin 等,提供特定HTTP方法的实现。
* Viewsets: 将 listcreateretrieveupdatedestroy 等操作打包成一个类,配合路由器使用。

我们使用 ModelViewSet 来简化代码:

“`python

blog/views.py

from rest_framework import viewsets, permissions
from .models import Post
from .serializers import PostSerializer

class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all().order_by(‘-created_at’)
serializer_class = PostSerializer
permission_classes = [permissions.IsAuthenticatedOrReadOnly] # 允许认证用户写,匿名用户读

def perform_create(self, serializer):
    # 当创建Post时,自动将当前请求用户设为作者
    serializer.save(author=self.request.user)

“`

3.4 URL 配置 (urls.py)

DRF的路由器可以自动为Viewsets生成URL模式。

“`python

myproject/urls.py (项目级别)

from django.contrib import admin
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from blog import views

router = DefaultRouter()
router.register(r’posts’, views.PostViewSet) # 注册PostViewSet

urlpatterns = [
path(‘admin/’, admin.site.urls),
path(‘api/’, include(router.urls)), # 包含DRF生成的API URL
path(‘api-auth/’, include(‘rest_framework.urls’)), # 提供登录/注销视图 (可选,用于Browsable API)
]
“`

“`python

blog/urls.py (应用级别,如果你的应用有自己的urls.py)

暂时不需要,因为我们直接在项目urls.py中使用了路由器

“`

4. 测试你的API

运行Django开发服务器:
bash
python manage.py runserver

打开浏览器访问 http://127.0.0.1:8000/api/posts/,你将看到DRF提供的Browsable API界面。

你可以:
* 查看文章列表: 通过GET请求。
* 创建新文章: 如果你已登录,可以通过POST请求创建新文章。
* 查看单篇文章: 访问 http://127.0.0.1:8000/api/posts/1/ (假设ID为1)。
* 更新文章: 通过PUT/PATCH请求。
* 删除文章: 通过DELETE请求。

5. 高级特性

5.1 权限与认证

DRF提供了强大的权限和认证机制。

认证类 (Authentication Classes)
定义用户如何通过凭证识别身份。
* SessionAuthentication: Django的会话认证。
* BasicAuthentication: HTTP基本认证。
* TokenAuthentication: 基于Token的认证。
* JWTAuthentication: (通常通过第三方库实现) JSON Web Token认证。

权限类 (Permission Classes)
定义认证用户可以执行哪些操作。
* AllowAny: 允许所有请求。
* IsAuthenticated: 仅允许认证用户。
* IsAdminUser: 仅允许管理员用户。
* IsAuthenticatedOrReadOnly: 认证用户可读写,匿名用户只读。
* DjangoModelPermissions: 基于Django模型的权限。

你可以在全局 settings.py 中配置默认权限,也可以在视图类中重写:

python
class PostViewSet(viewsets.ModelViewSet):
# ...
permission_classes = [permissions.IsAuthenticatedOrReadOnly]

你也可以创建自定义权限类,例如,只允许作者编辑自己的文章:

“`python

blog/permissions.py

from rest_framework import permissions

class IsAuthorOrReadOnly(permissions.BasePermission):
“””
自定义权限:只允许对象的所有者编辑。
“””
def has_object_permission(self, request, view, obj):
# 允许GET, HEAD, OPTIONS请求
if request.method in permissions.SAFE_METHODS:
return True

    # 写权限只允许给文章的作者
    return obj.author == request.user

“`

然后在视图中使用:

“`python

blog/views.py

from .permissions import IsAuthorOrReadOnly

class PostViewSet(viewsets.ModelViewSet):
# …
permission_classes = [IsAuthorOrReadOnly]
“`

5.2 过滤、搜索与排序

过滤 (Filtering)
使用 django-filter 库可以轻松实现过滤功能。

  1. 安装 django-filter: pip install django-filter
  2. 添加到 INSTALLED_APPS (如果未添加): 'django_filters'
  3. settings.py 中设置默认后端:
    python
    REST_FRAMEWORK = {
    # ...
    'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'],
    }
  4. 创建过滤器类:

    “`python

    blog/filters.py

    import django_filters
    from .models import Post

    class PostFilter(django_filters.FilterSet):
    min_created_at = django_filters.DateTimeFilter(field_name=”created_at”, lookup_expr=’gte’)
    max_created_at = django_filters.DateTimeFilter(field_name=”created_at”, lookup_expr=’lte’)

    class Meta:
        model = Post
        fields = ['author', 'created_at', 'title']
    

    “`
    5. 在视图中应用过滤器:

    “`python

    blog/views.py

    from django_filters.rest_framework import DjangoFilterBackend
    from .filters import PostFilter

    class PostViewSet(viewsets.ModelViewSet):
    # …
    filter_backends = [DjangoFilterBackend]
    filterset_class = PostFilter
    # 或者直接使用 fields: filterset_fields = [‘author__username’, ‘title’]
    “`

现在你可以通过URL参数进行过滤,例如:http://127.0.0.1:8000/api/posts/?author=1&title=test

搜索 (Searching)

“`python
from rest_framework import filters

class PostViewSet(viewsets.ModelViewSet):
# …
filter_backends = [filters.SearchFilter]
search_fields = [‘title’, ‘content’] # 允许搜索的字段
“`

访问 http://127.0.0.1:8000/api/posts/?search=keyword

排序 (Ordering)

“`python
from rest_framework import filters

class PostViewSet(viewsets.ModelViewSet):
# …
filter_backends = [filters.OrderingFilter]
ordering_fields = [‘created_at’, ‘title’] # 允许排序的字段
ordering = [‘-created_at’] # 默认排序
“`

访问 http://127.0.0.1:8000/api/posts/?ordering=-created_at

5.3 分页 (Pagination)

DRF提供了多种分页器,你可以在 settings.py 中全局配置,也可以在视图中指定:

“`python

settings.py

REST_FRAMEWORK = {
‘DEFAULT_PAGINATION_CLASS’: ‘rest_framework.pagination.PageNumberPagination’,
‘PAGE_SIZE’: 10
}

views.py (自定义分页器)

from rest_framework.pagination import LimitOffsetPagination

class CustomPagination(LimitOffsetPagination):
default_limit = 5
max_limit = 20

class PostViewSet(viewsets.ModelViewSet):
# …
pagination_class = CustomPagination
“`

5.4 序列化器深度和嵌套

你可能希望在获取文章时,也一并获取作者的详细信息,而不是仅仅ID。在 PostSerializer 中,我们已经使用了嵌套序列化器 author = UserSerializer(read_only=True)。DRF支持更深的嵌套,但要注意性能开销。

6. 总结与展望

本教程涵盖了Django REST Framework的基础到一些高级特性,包括模型、序列化器、视图、URL路由、权限认证、过滤、搜索、排序和分页。DRF的强大之处在于其可插拔和可定制性,你可以根据项目的具体需求进行灵活调整。

下一步你可以探索:
* 自定义序列化器字段: 处理更复杂的数据结构。
* 文件上传: 如何通过API处理文件。
* 测试API: 编写单元测试和集成测试。
* 视图集的动作 (Actions): 为视图集添加额外的自定义方法。
* 缓存: 提升API性能。
* Swagger/OpenAPI文档生成: 使用 drf-yasgrest_framework_simplejwt 等工具自动生成API文档。
* WebSockets: 结合Django Channels构建实时API。

Django REST Framework是构建高效、可维护和可扩展Web API的绝佳选择。通过不断实践和探索,你将能够驾驭它,为你的项目提供强大的后端支持。


滚动至顶部