Django REST Framework 实战:构建 RESTful API
Django REST Framework(简称DRF)是一个强大而灵活的工具,用于构建 Web API。它是Django生态中最流行的REST API框架,被广泛用于前后端分离项目、移动端后端、微服务架构等场景。本文将从零开始,带你掌握DRF的核心用法。
一、环境准备
1. 安装依赖
pip install django djangorestframework
2. 创建项目
django-admin startproject myapi
cd myapi
python manage.py startapp blog
3. 配置settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'blog',
]
二、定义模型
在 blog/models.py 中创建文章模型:
from django.db import models
class Article(models.Model):
title = models.CharField('标题', max_length=200)
content = models.TextField('内容')
author = models.CharField('作者', max_length=100)
created_at = models.DateTimeField('创建时间', auto_now_add=True)
updated_at = models.DateTimeField('更新时间', auto_now=True)
is_published = models.BooleanField('是否发布', default=False)
class Meta:
verbose_name = '文章'
verbose_name_plural = '文章'
ordering = ['-created_at']
def __str__(self):
return self.title
执行迁移:
python manage.py makemigrations
python manage.py migrate
三、序列化器(Serializer)
序列化器是DRF的核心概念之一,负责将模型实例转换为JSON数据。
在 blog/serializers.py 中创建:
from rest_framework import serializers
from .models import Article
class ArticleSerializer(serializers.ModelSerializer):
class Meta:
model = Article
fields = ['id', 'title', 'content', 'author', 'created_at', 'updated_at', 'is_published']
read_only_fields = ['created_at', 'updated_at']
四、视图(View)
方式一:函数视图
from rest_framework.decorators import api_view
from rest_framework.response import Response
from rest_framework import status
from .models import Article
from .serializers import ArticleSerializer
@api_view(['GET', 'POST'])
def article_list(request):
if request.method == 'GET':
articles = Article.objects.all()
serializer = ArticleSerializer(articles, many=True)
return Response(serializer.data)
elif request.method == 'POST':
serializer = ArticleSerializer(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 article_detail(request, pk):
try:
article = Article.objects.get(pk=pk)
except Article.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
if request.method == 'GET':
serializer = ArticleSerializer(article)
return Response(serializer.data)
elif request.method == 'PUT':
serializer = ArticleSerializer(article, 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':
article.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
方式二:类视图(推荐)
from rest_framework import generics
from .models import Article
from .serializers import ArticleSerializer
class ArticleListCreate(generics.ListCreateAPIView):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
class ArticleDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
方式三:ViewSet(最推荐)
from rest_framework import viewsets
from .models import Article
from .serializers import ArticleSerializer
class ArticleViewSet(viewsets.ModelViewSet):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
def get_queryset(self):
queryset = Article.objects.all()
author = self.request.query_params.get('author')
if author:
queryset = queryset.filter(author=author)
return queryset
五、路由配置
在项目 urls.py 中配置:
from django.contrib import admin
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from blog.views import ArticleViewSet
router = DefaultRouter()
router.register(r'articles', ArticleViewSet)
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include(router.urls)),
]
六、API接口一览
配置完成后,DRF自动生成以下接口:
- GET /api/articles/ 获取文章列表
- POST /api/articles/ 创建新文章
- GET /api/articles/{id}/ 获取文章详情
- PUT /api/articles/{id}/ 更新文章
- PATCH /api/articles/{id}/ 部分更新文章
- DELETE /api/articles/{id}/ 删除文章
七、认证与权限
1. 添加认证
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework.authentication.SessionAuthentication',
'rest_framework.authentication.TokenAuthentication',
],
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.IsAuthenticatedOrReadOnly',
],
}
2. 自定义权限
from rest_framework import permissions
class IsAuthorOrReadOnly(permissions.BasePermission):
def has_object_permission(self, request, view, obj):
if request.method in permissions.SAFE_METHODS:
return True
return obj.author == request.user.username
八、分页与过滤
1. 分页配置
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 10,
}
2. 过滤
安装django-filter:
pip install django-filter
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'],
}
九、测试API
使用curl测试:
# 获取文章列表
curl http://localhost:8000/api/articles/
# 创建新文章
curl -X POST http://localhost:8000/api/articles/ -H 'Content-Type: application/json' -d '{"title": "测试文章", "content": "这是内容", "author": "张三"}'
# 更新文章
curl -X PUT http://localhost:8000/api/articles/1/ -H 'Content-Type: application/json' -d '{"title": "更新后的标题", "content": "更新后的内容", "author": "张三"}'
# 删除文章
curl -X DELETE http://localhost:8000/api/articles/1/
十、总结
本文介绍了Django REST Framework的核心用法:
- 序列化器:负责数据的序列化和反序列化
- 视图:处理HTTP请求,推荐使用ViewSet
- 路由:使用DefaultRouter自动生成路由
- 认证权限:保护API接口安全
- 分页过滤:提升API的可用性
DRF的生态系统非常丰富,还有更多高级功能如JWT认证(djangorestframework-simplejwt)、API文档自动生成(drf-spectacular)等。
希望这篇实战教程对你有帮助!