Django REST Framework 第一个API #
一、项目准备 #
1.1 创建项目和应用 #
bash
# 创建项目
django-admin startproject myapi
cd myapi
# 创建应用
python manage.py startapp articles
1.2 注册应用 #
编辑 myapi/settings.py:
python
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'articles',
]
二、创建模型 #
2.1 定义Article模型 #
编辑 articles/models.py:
python
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
2.2 执行数据库迁移 #
bash
python manage.py makemigrations
python manage.py migrate
三、创建序列化器 #
3.1 什么是序列化器 #
序列化器负责将模型实例转换为JSON格式,以及将JSON数据验证并转换为模型实例。
text
┌─────────────────┐ ┌─────────────────┐
│ 模型实例 │────────▶│ JSON数据 │
│ (Python对象) │◀────────│ (API响应) │
└─────────────────┘ 序列化 └─────────────────┘
3.2 创建序列化器 #
创建 articles/serializers.py:
python
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 = ['id', 'created_at', 'updated_at']
3.3 序列化器的作用 #
| 功能 | 说明 |
|---|---|
| 序列化 | 将模型实例转换为JSON |
| 反序列化 | 将JSON转换为模型实例 |
| 数据验证 | 验证输入数据的合法性 |
| 字段控制 | 控制哪些字段可以被访问 |
四、创建视图 #
4.1 方式一:函数视图 #
编辑 articles/views.py:
python
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)
4.2 方式二:类视图 #
python
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from .models import Article
from .serializers import ArticleSerializer
class ArticleList(APIView):
def get(self, request):
articles = Article.objects.all()
serializer = ArticleSerializer(articles, many=True)
return Response(serializer.data)
def post(self, request):
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)
class ArticleDetail(APIView):
def get_object(self, pk):
try:
return Article.objects.get(pk=pk)
except Article.DoesNotExist:
return None
def get(self, request, pk):
article = self.get_object(pk)
if article is None:
return Response(status=status.HTTP_404_NOT_FOUND)
serializer = ArticleSerializer(article)
return Response(serializer.data)
def put(self, request, pk):
article = self.get_object(pk)
if article is None:
return Response(status=status.HTTP_404_NOT_FOUND)
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)
def delete(self, request, pk):
article = self.get_object(pk)
if article is None:
return Response(status=status.HTTP_404_NOT_FOUND)
article.delete()
return Response(status=status.HTTP_204_NO_CONTENT)
4.3 方式三:通用视图(推荐) #
python
from rest_framework import generics
from .models import Article
from .serializers import ArticleSerializer
class ArticleList(generics.ListCreateAPIView):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
class ArticleDetail(generics.RetrieveUpdateDestroyAPIView):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
4.4 方式四:视图集(最简洁) #
python
from rest_framework import viewsets
from .models import Article
from .serializers import ArticleSerializer
class ArticleViewSet(viewsets.ModelViewSet):
queryset = Article.objects.all()
serializer_class = ArticleSerializer
五、配置URL #
5.1 配置应用URL #
创建 articles/urls.py:
函数视图URL:
python
from django.urls import path
from . import views
urlpatterns = [
path('articles/', views.article_list, name='article-list'),
path('articles/<int:pk>/', views.article_detail, name='article-detail'),
]
类视图URL:
python
from django.urls import path
from .views import ArticleList, ArticleDetail
urlpatterns = [
path('articles/', ArticleList.as_view(), name='article-list'),
path('articles/<int:pk>/', ArticleDetail.as_view(), name='article-detail'),
]
视图集URL(使用路由器):
python
from rest_framework.routers import DefaultRouter
from .views import ArticleViewSet
router = DefaultRouter()
router.register(r'articles', ArticleViewSet)
urlpatterns = router.urls
5.2 配置项目URL #
编辑 myapi/urls.py:
python
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api-auth/', include('rest_framework.urls')),
path('api/', include('articles.urls')),
]
六、注册Admin #
编辑 articles/admin.py:
python
from django.contrib import admin
from .models import Article
@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
list_display = ['id', 'title', 'author', 'created_at', 'is_published']
list_filter = ['is_published', 'created_at']
search_fields = ['title', 'content', 'author']
ordering = ['-created_at']
七、测试API #
7.1 启动服务器 #
bash
python manage.py runserver
7.2 使用浏览器测试 #
访问 http://127.0.0.1:8000/api/articles/,你将看到DRF的可视化API界面:
text
HTTP 200 OK
Allow: GET, POST, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept
[]
7.3 创建文章 #
在浏览器界面中填写表单,或使用curl:
bash
curl -X POST http://127.0.0.1:8000/api/articles/ \
-H "Content-Type: application/json" \
-d '{
"title": "我的第一篇文章",
"content": "这是文章内容",
"author": "张三"
}'
响应:
json
{
"id": 1,
"title": "我的第一篇文章",
"content": "这是文章内容",
"author": "张三",
"created_at": "2024-01-15T10:30:00Z",
"updated_at": "2024-01-15T10:30:00Z",
"is_published": false
}
7.4 获取文章列表 #
bash
curl http://127.0.0.1:8000/api/articles/
7.5 获取单篇文章 #
bash
curl http://127.0.0.1:8000/api/articles/1/
7.6 更新文章 #
bash
curl -X PUT http://127.0.0.1:8000/api/articles/1/ \
-H "Content-Type: application/json" \
-d '{
"title": "更新后的标题",
"content": "更新后的内容",
"author": "张三",
"is_published": true
}'
7.7 删除文章 #
bash
curl -X DELETE http://127.0.0.1:8000/api/articles/1/
八、HTTP方法映射 #
| HTTP方法 | URL | 操作 | 说明 |
|---|---|---|---|
| GET | /api/articles/ | list | 获取文章列表 |
| POST | /api/articles/ | create | 创建新文章 |
| GET | /api/articles/{id}/ | retrieve | 获取单篇文章 |
| PUT | /api/articles/{id}/ | update | 完整更新文章 |
| PATCH | /api/articles/{id}/ | partial_update | 部分更新文章 |
| DELETE | /api/articles/{id}/ | destroy | 删除文章 |
九、视图方式对比 #
| 方式 | 代码量 | 灵活性 | 适用场景 |
|---|---|---|---|
| 函数视图 | 多 | 高 | 需要精细控制的场景 |
| 类视图 | 中 | 中 | 需要代码复用的场景 |
| 通用视图 | 少 | 中 | 标准CRUD操作 |
| 视图集 | 最少 | 低 | 快速开发标准API |
十、完整项目结构 #
text
myapi/
├── manage.py
├── myapi/
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ ├── asgi.py
│ └── wsgi.py
└── articles/
├── __init__.py
├── admin.py
├── apps.py
├── migrations/
│ └── __init__.py
├── models.py
├── serializers.py
├── tests.py
├── urls.py
└── views.py
十一、总结 #
本章我们创建了第一个DRF API,学习了:
- 模型定义:使用Django ORM定义数据模型
- 序列化器:实现数据的序列化和反序列化
- 视图:多种方式实现API视图
- URL配置:将视图映射到URL
现在你已经掌握了创建基本API的方法,让我们继续深入学习序列化器的更多功能!
最后更新:2026-03-28