Django REST框架入门教程从零基础到实战开发详解如何快速掌握API构建技巧

什么是Django REST框架及其核心优势
Django REST框架(简称DRF)是基于Django的一个强大且灵活的工具包,用于构建Web API。它建立在Django的成熟生态系统之上,提供了序列化、认证、权限控制等开箱即用的功能,极大地简化了RESTful API的开发流程。对于初学者来说,掌握DRF能够快速构建出符合行业标准的API接口。
DRF的核心优势在于其高度的可扩展性和模块化设计。它支持多种认证方式(如Token认证、JWT认证),内置了强大的序列化器来处理数据转换,并提供了丰富的视图集来减少重复代码。例如,使用DRF的ModelViewSet,只需几行代码就能实现完整的CRUD操作,而传统Django视图可能需要编写数十行代码。此外,DRF还自动生成交互式API文档,方便前端开发者或测试人员调试接口。
环境搭建与项目初始化
在开始编码前,我们需要搭建开发环境。首先确保已安装Python(推荐3.8+版本),然后创建一个虚拟环境并安装必要的包。以下是详细步骤:
# 创建项目目录并进入
mkdir drf_tutorial && cd drf_tutorial

# 创建虚拟环境(Windows)
python -m venv venv
venv\Scripts\activate

# 创建虚拟环境(macOS/Linux)
python3 -m venv venv
source venv/bin/activate

# 安装Django和Django REST框架
pip install django djangorestframework

# 初始化Django项目
django-admin startproject tutorial .
python manage.py startapp quickstart
接下来,在项目的settings.py中添加必要的配置:
# tutorial/settings.py
INSTALLED_APPS = [
‘django.contrib.admin’,
‘django.contrib.auth’,
‘django.contrib.contenttypes’,
‘django.contrib.sessions’,
‘django.contrib.messages’,
‘django.contrib.staticfiles’,
‘rest_framework’, # 添加DRF
‘quickstart’, # 添加我们的应用
]

# 配置数据库(默认使用SQLite,无需修改)
DATABASES = {
‘default’: {
‘ENGINE’: ‘django.db.backends.sqlite3’,
‘NAME’: BASE_DIR / ‘db.sqlite3’,
}
}

# 添加DRF的全局配置(可选,但推荐)
REST_FRAMEWORK = {
‘DEFAULT_PAGINATION_CLASS’: ‘rest_framework.pagination.PageNumberPagination’,
‘PAGE_SIZE’: 10
}
完成配置后,运行迁移命令初始化数据库:
python manage.py migrate
python manage.py createsuperuser # 按提示创建管理员账号
序列化器(Serializer)详解
序列化器是DRF中最重要的组件之一,它负责将复杂的数据类型(如QuerySet或模型实例)转换为原生Python数据类型,进而可以渲染为JSON等格式。同时,它也处理反向操作:将客户端提交的数据解析为模型实例。
首先,在quickstart应用中创建serializers.py文件:
# quickstart/serializers.py
from django.contrib.auth.models import User
from rest_framework import serializers

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

# 自定义一个更复杂的序列化器示例
class ProductSerializer(serializers.Serializer):
id = serializers.IntegerField(read_only=True)
name = serializers.CharField(max_length=100)
price = serializers.DecimalField(max_digits=8, decimal_places=2)
stock = serializers.IntegerField()

# 自定义验证方法
def validate_price(self, value):
if value <= 0: raise serializers.ValidationError("价格必须大于0") return value def create(self, validated_data): # 用于创建新实例 return Product.objects.create(**validated_data) def update(self, instance, validated_data): # 用于更新现有实例 instance.name = validated_data.get('name', instance.name) instance.price = validated_data.get('price', instance.price) instance.stock = validated_data.get('stock', instance.stock) instance.save() return instance ModelSerializer相比普通Serializer的优势在于它会自动根据模型生成字段,并默认实现create和update方法。但有时我们需要自定义字段或验证逻辑,这时可以灵活地重写相关方法。 视图(View)开发:从函数视图到类视图 DRF提供了多种视图编写方式,从简单的函数视图到高度封装的类视图。我们先从一个简单的函数视图开始: # quickstart/views.py from rest_framework.decorators import api_view from rest_framework.response import Response from django.contrib.auth.models import User from .serializers import UserSerializer @api_view(['GET']) def user_list(request): users = User.objects.all() serializer = UserSerializer(users, many=True) return Response(serializer.data) 但更推荐使用类视图,因为它们提供了更好的代码复用和结构化。以下是使用通用视图类的示例: # quickstart/views.py from rest_framework import generics from django.contrib.auth.models import User from .serializers import UserSerializer class UserListCreateView(generics.ListCreateAPIView): queryset = User.objects.all() serializer_class = UserSerializer class UserRetrieveUpdateDestroyView(generics.RetrieveUpdateDestroyAPIView): queryset = User.objects.all() serializer_class = UserSerializer 对于更复杂的场景,可以使用ViewSet和ModelViewSet。ViewSet将多个相关操作组合到一个类中: # quickstart/views.py from rest_framework import viewsets from django.contrib.auth.models import User from .serializers import UserSerializer class UserViewSet(viewsets.ModelViewSet): """ API endpoint that allows users to be viewed or edited. """ queryset = User.objects.all().order_by('-date_joined') serializer_class = UserSerializer ViewSet会自动为以下操作生成路由映射: list (GET /users/) - 获取用户列表 create (POST /users/) - 创建新用户 retrieve (GET /users/{id}/) - 获取单个用户 update (PUT /users/{id}/) - 更新用户 partial_update (PATCH /users/{id}/) - 部分更新用户 destroy (DELETE /users/{id}/) - 删除用户 路由配置与URL设计 DRF提供了强大的路由系统,可以自动为ViewSet生成URL配置。首先在项目的urls.py中配置: # tutorial/urls.py from django.contrib import admin from django.urls import path, include from rest_framework.routers import DefaultRouter from quickstart import views # 创建路由器并注册视图集 router = DefaultRouter() router.register(r'users', views.UserViewSet) urlpatterns = [ path('admin/', admin.site.urls), path('api/', include(router.urls)), # 自动包含所有注册的路由 path('api-auth/', include('rest_framework.urls')), # 可选:用于浏览API时的登录认证 ] 对于没有使用ViewSet的视图,可以手动配置URL: # 手动配置URL示例 from django.urls import path from quickstart.views import user_list urlpatterns = [ path('users/', user_list, name='user-list'), ] 认证与权限控制 DRF提供了多种认证方案,包括基本认证、Token认证、Session认证等。以下是如何配置和使用这些认证: 1. 基本认证(仅用于开发测试) 在settings.py中添加: REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework.authentication.BasicAuthentication', 'rest_framework.authentication.SessionAuthentication', ], 'DEFAULT_PERMISSION_CLASSES': [ 'rest_framework.permissions.IsAuthenticated', ] } 2. Token认证(生产环境推荐) 首先安装并配置: pip install djangorestframework-simplejwt 在settings.py中添加: INSTALLED_APPS = [ ... 'rest_framework_simplejwt', ] REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework_simplejwt.authentication.JWTAuthentication', ], } 在urls.py中添加Token获取端点: from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView urlpatterns = [ ... path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), ] 3. 自定义权限类 可以创建自己的权限类: # quickstart/permissions.py from rest_framework import permissions class IsOwnerOrReadOnly(permissions.BasePermission): """ 自定义权限:只允许对象的所有者编辑它。 """ def has_object_permission(self, request, view, obj): # 读权限对所有请求都开放 if request.method in permissions.SAFE_METHODS: return True # 只有对象的所有者才有写权限 return obj.owner == request.user 然后在视图中使用: from .permissions import IsOwnerOrReadOnly class ProductViewSet(viewsets.ModelViewSet): queryset = Product.objects.all() serializer_class = ProductSerializer permission_classes = [IsAuthenticated, IsOwnerOrReadOnly] 实战开发:构建一个完整的博客API 让我们通过一个完整的博客系统示例来整合以上所有知识点。我们将创建包含文章、分类和评论的API。 1. 创建模型 # blog/models.py from django.db import models from django.contrib.auth.models import User class Category(models.Model): name = models.CharField(max_length=100) def __str__(self): return self.name class Post(models.Model): title = models.CharField(max_length=200) content = models.TextField() author = models.ForeignKey(User, on_delete=models.CASCADE) category = models.ForeignKey(Category, on_delete=models.SET_NULL, null=True) created_at = models.DateTimeField(auto_now_add=True) updated_at = models.DateTimeField(auto_now=True) def __str__(self): return self.title class Comment(models.Model): post = models.ForeignKey(Post, related_name='comments', on_delete=models.CASCADE) author = models.ForeignKey(User, on_delete=models.CASCADE) content = models.TextField() created_at = models.DateTimeField(auto_now_add=True) def __str__(self): return f"Comment by {self.author.username} on {self.post.title}" 2. 创建序列化器 # blog/serializers.py from rest_framework import serializers from .models import Category, Post, Comment from django.contrib.auth.models import User class CategorySerializer(serializers.ModelSerializer): class Meta: model = Category fields = ['id', 'name'] class CommentSerializer(serializers.ModelSerializer): author = serializers.ReadOnlyField(source='author.username') class Meta: model = Comment fields = ['id', 'author', 'content', 'created_at'] class PostSerializer(serializers.ModelSerializer): author = serializers.ReadOnlyField(source='author.username') category = CategorySerializer(read_only=True) category_id = serializers.IntegerField(write_only=True) comments = CommentSerializer(many=True, read_only=True) class Meta: model = Post fields = ['id', 'title', 'content', 'author', 'category', 'category_id', 'comments', 'created_at', 'updated_at'] def validate_category_id(self, value): if not Category.objects.filter(id=value).exists(): raise serializers.ValidationError("Category does not exist") return value 3. 创建视图 # blog/views.py from rest_framework import viewsets, permissions, generics from rest_framework.decorators import action from rest_framework.response import Response from .models import Category, Post, Comment from .serializers import CategorySerializer, PostSerializer, CommentSerializer from .permissions import IsOwnerOrReadOnly class CategoryViewSet(viewsets.ModelViewSet): queryset = Category.objects.all() serializer_class = CategorySerializer permission_classes = [permissions.IsAuthenticatedOrReadOnly] class PostViewSet(viewsets.ModelViewSet): queryset = Post.objects.all() serializer_class = PostSerializer permission_classes = [permissions.IsAuthenticatedOrReadOnly, IsOwnerOrReadOnly] def perform_create(self, serializer): serializer.save(author=self.request.user) @action(detail=True, methods=['get']) def comments(self, request, pk=None): post = self.get_object() comments = post.comments.all() serializer = CommentSerializer(comments, many=True) return Response(serializer.data) class CommentCreateView(generics.CreateAPIView): queryset = Comment.objects.all() serializer_class = CommentSerializer permission_classes = [permissions.IsAuthenticated] def perform_create(self, serializer): serializer.save(author=self.request.user) class CommentDetailView(generics.RetrieveUpdateDestroyAPIView): queryset = Comment.objects.all() serializer_class = CommentSerializer permission_classes = [permissions.IsAuthenticated, IsOwnerOrReadOnly] 4. 配置路由 # blog/urls.py from django.urls import path, include from rest_framework.routers import DefaultRouter from . import views router = DefaultRouter() router.register(r'categories', views.CategoryViewSet) router.register(r'posts', views.PostViewSet) urlpatterns = [ path('', include(router.urls)), path('posts//comments/’, views.CommentCreateView.as_view(), name=’comment-create’),
path(‘comments//’, views.CommentDetailView.as_view(), name=’comment-detail’),
]
在主urls.py中包含博客应用的路由:
# tutorial/urls.py
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from quickstart import views as quickstart_views
from blog import views as blog_views

router = DefaultRouter()
router.register(r’users’, quickstart_views.UserViewSet)
router.register(r’categories’, blog_views.CategoryViewSet)
router.register(r’posts’, blog_views.PostViewSet)

urlpatterns = [
path(‘admin/’, admin.site.urls),
path(‘api/’, include(router.urls)),
path(‘api-auth/’, include(‘rest_framework.urls’)),
]
测试与调试API
DRF提供了强大的测试工具。我们可以使用内置的API浏览器测试接口,也可以编写自动化测试。
1. 使用API浏览器
启动开发服务器:
python manage.py runserver
访问
http://127.0.0.1:8000/api/
即可看到所有注册的端点。DRF会自动为每个端点生成一个交互式界面,支持GET、POST、PUT、DELETE等操作。
2. 编写自动化测试
# blog/tests.py
from django.test import TestCase
from django.contrib.auth.models import User
from rest_framework.test import APIClient
from rest_framework import status
from .models import Category, Post

class BlogAPITestCase(TestCase):
def setUp(self):
self.client = APIClient()
self.user = User.objects.create_user(username=’testuser’, password=’testpass’)
self.category = Category.objects.create(name=’Tech’)
self.client.force_authenticate(user=self.user)

def test_create_post(self):
response = self.client.post(‘/api/posts/’, {
‘title’: ‘Test Post’,
‘content’: ‘Test content’,
‘category_id’: self.category.id
})
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertEqual(Post.objects.count(), 1)
self.assertEqual(Post.objects.first().title, ‘Test Post’)

def test_unauthenticated_create(self):
self.client.force_authenticate(user=None)
response = self.client.post(‘/api/posts/’, {
‘title’: ‘Test Post’,
‘content’: ‘Test content’,
‘category_id’: self.category.id
})
self.assertEqual(response.status_code, status.HTTP_403_FORBIDDEN)
运行测试:
python manage.py test
高级技巧与最佳实践
1. 分页与过滤
# 在settings.py中配置全局分页
REST_FRAMEWORK = {
‘DEFAULT_PAGINATION_CLASS’: ‘rest_framework.pagination.PageNumberPagination’,
‘PAGE_SIZE’: 20,
‘DEFAULT_FILTER_BACKENDS’: [‘django_filters.rest_framework.DjangoFilterBackend’],
}

# 在视图中添加过滤
from django_filters.rest_framework import DjangoFilterBackend
from rest_framework import filters

class PostViewSet(viewsets.ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
filterset_fields = [‘category’, ‘author’]
search_fields = [‘title’, ‘content’]
ordering_fields = [‘created_at’, ‘title’]
2. 自定义分页类
# blog/pagination.py
from rest_framework.pagination import PageNumberPagination
from rest_framework.response import Response

class CustomPagination(PageNumberPagination):
page_size = 10
page_size_query_param = ‘page_size’
max_page_size = 100

def get_paginated_response(self, data):
return Response({
‘links’: {
‘next’: self.get_next_link(),
‘previous’: self.get_previous_link(),
},
‘count’: self.page.paginator.count,
‘total_pages’: self.page.paginator.num_pages,
‘current_page’: self.page.number,
‘results’: data
})
3. 限流(Throttling)
# settings.py
REST_FRAMEWORK = {
‘DEFAULT_THROTTLE_CLASSES’: [
‘rest_framework.throttling.AnonRateThrottle’,
‘rest_framework.throttling.UserRateThrottle’
],
‘DEFAULT_THROTTLE_RATES’: {
‘anon’: ‘100/day’,
‘user’: ‘1000/day’
}
}
4. 版本控制
# settings.py
REST_FRAMEWORK = {
‘DEFAULT_VERSIONING_CLASS’: ‘rest_framework.versioning.URLPathVersioning’,
‘DEFAULT_VERSION’: ‘v1’,
‘ALLOWED_VERSIONS’: [‘v1’, ‘v2’],
}

# 在URL中配置
urlpatterns = [
path(‘api/v1/’, include(‘api_v1.urls’)),
path(‘api/v2/’, include(‘api_v2.urls’)),
]
部署准备
在生产环境中部署DRF项目时,需要注意以下几点:
使用生产级Web服务器
:不要使用Django的开发服务器。推荐使用Gunicorn或uWSGI配合Nginx:
pip install gunicorn
gunicorn –bind 0.0.0.0:8000 tutorial.wsgi:application
配置静态文件
:确保正确配置静态文件服务:
# settings.py
STATIC_URL = ‘/static/’
STATIC_ROOT = os.path.join(BASE_DIR, ‘staticfiles’)
安全配置
:
# settings.py
DEBUG = False
ALLOWED_HOSTS = [‘yourdomain.com’]
SECRET_KEY = ‘your-production-secret-key’ # 从环境变量读取更好
数据库优化
:考虑使用PostgreSQL等更强大的数据库,并配置连接池。
总结
通过本教程,我们从零开始学习了Django REST框架的核心概念和实战技巧。关键知识点包括:
序列化器
:数据转换的核心,支持自定义验证和方法
视图系统
:从函数视图到ViewSet的演进,减少重复代码
路由配置
:自动URL生成和手动配置的结合
认证与权限
:多种认证方案和细粒度的权限控制
实战项目
:完整的博客API开发流程
高级特性
:分页、过滤、限流、版本控制等生产级功能
要快速掌握API构建技巧,建议:
从简单项目开始,逐步增加复杂度
多使用DRF的内置功能,避免重复造轮子
充分利用测试保证API质量
阅读官方文档和优秀开源项目
DRF的学习曲线相对平缓,但功能深度足够。通过实践本教程的博客API示例,你应该能够独立开发中等复杂度的RESTful API了。继续深入学习可以关注异步支持、GraphQL集成等高级主题。