Python使用Django进行RESTful API开发
1. 准备工作
在开始使用 Django 进行 RESTful API 开发之前,确保你已经安装了 Python 和 Django。如果还没有安装,可以按照以下步骤进行安装:
- 安装 Python:从 Python 官方网站(https://www.python.org/downloads/)下载并安装最新版本的 Python。安装过程中,记得勾选“Add Python to PATH”选项,以便在命令行中能够直接使用 Python 命令。
- 安装 Django:打开命令行,运行以下命令安装 Django:
pip install django
此外,我们还需要安装 djangorestframework
,它是一个强大而灵活的用于构建 Web API 的工具包。运行以下命令进行安装:
pip install djangorestframework
2. 创建 Django 项目
首先,我们需要创建一个新的 Django 项目。在命令行中,进入你想要创建项目的目录,然后运行以下命令:
django - admin startproject myproject
这将在当前目录下创建一个名为 myproject
的 Django 项目。项目结构如下:
myproject/
├── myproject/
│ ├── __init__.py
│ ├── settings.py
│ ├── urls.py
│ └── asgi.py
└── manage.py
myproject/
是项目的根目录,包含项目的配置文件和一些初始化文件。settings.py
包含项目的所有配置信息,如数据库设置、安装的应用等。urls.py
负责定义项目的 URL 模式,将不同的 URL 映射到相应的视图函数。manage.py
是一个命令行工具,用于与项目进行交互,如运行服务器、创建数据库迁移等。
3. 创建 Django 应用
在 Django 项目中,应用是一个独立的功能模块。我们需要创建一个应用来处理 API 相关的逻辑。在项目根目录(即包含 manage.py
的目录)下运行以下命令:
python manage.py startapp api
这将创建一个名为 api
的 Django 应用。应用目录结构如下:
api/
├── __init__.py
├── admin.py
├── apps.py
├── models.py
├── tests.py
└── views.py
models.py
用于定义数据库模型。views.py
包含处理 HTTP 请求的视图函数。admin.py
用于配置 Django 管理界面。
4. 定义数据库模型
假设我们要开发一个简单的博客 API,其中包含文章(Post)和作者(Author)两个模型。打开 api/models.py
文件,编写以下代码:
from django.db import models
class Author(models.Model):
name = models.CharField(max_length = 100)
email = models.EmailField(unique = True)
class Post(models.Model):
title = models.CharField(max_length = 200)
content = models.TextField()
author = models.ForeignKey(Author, on_delete = models.CASCADE)
created_at = models.DateTimeField(auto_now_add = True)
在上述代码中:
Author
模型有两个字段:name
(字符串类型,最大长度为 100)和email
(电子邮件类型,且必须唯一)。Post
模型有四个字段:title
(字符串类型,最大长度为 200),content
(文本类型),author
(外键关联到Author
模型,当关联的Author
被删除时,与之关联的Post
也会被删除),created_at
(日期时间类型,自动设置为对象创建时的时间)。
定义好模型后,我们需要创建数据库迁移并应用它们。在项目根目录下运行以下命令:
python manage.py makemigrations
python manage.py migrate
makemigrations
命令会检测模型的变化并生成迁移文件,migrate
命令则会将这些迁移应用到数据库中。
5. 创建序列化器
序列化器用于将 Django 模型实例转换为 JSON 格式(或其他格式),以便在 API 中进行传输,同时也可以将接收到的 JSON 数据反序列化为模型实例。在 api
应用目录下创建一个新文件 serializers.py
,并编写以下代码:
from rest_framework import serializers
from.models import Author, Post
class AuthorSerializer(serializers.ModelSerializer):
class Meta:
model = Author
fields = '__all__'
class PostSerializer(serializers.ModelSerializer):
author = AuthorSerializer(read_only = True)
class Meta:
model = Post
fields = '__all__'
在上述代码中:
AuthorSerializer
使用ModelSerializer
类自动为Author
模型生成序列化器,fields = '__all__'
表示包含模型的所有字段。PostSerializer
同样为Post
模型生成序列化器,并且将author
字段设置为AuthorSerializer
,read_only = True
表示在反序列化(创建或更新Post
时),author
字段不需要用户提供,而是由系统自动处理(例如,通过当前登录用户等方式)。
6. 创建视图
视图负责处理 HTTP 请求并返回响应。在 api/views.py
文件中编写以下代码:
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from.models import Author, Post
from.serializers import AuthorSerializer, PostSerializer
class AuthorListCreateView(APIView):
def get(self, request):
authors = Author.objects.all()
serializer = AuthorSerializer(authors, many = True)
return Response(serializer.data)
def post(self, request):
serializer = AuthorSerializer(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 AuthorDetailView(APIView):
def get_object(self, pk):
try:
return Author.objects.get(pk = pk)
except Author.DoesNotExist:
raise status.HTTP_404_NOT_FOUND
def get(self, request, pk):
author = self.get_object(pk)
serializer = AuthorSerializer(author)
return Response(serializer.data)
def put(self, request, pk):
author = self.get_object(pk)
serializer = AuthorSerializer(author, 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):
author = self.get_object(pk)
author.delete()
return Response(status = status.HTTP_204_NO_CONTENT)
class PostListCreateView(APIView):
def get(self, request):
posts = Post.objects.all()
serializer = PostSerializer(posts, many = True)
return Response(serializer.data)
def post(self, request):
serializer = PostSerializer(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 PostDetailView(APIView):
def get_object(self, pk):
try:
return Post.objects.get(pk = pk)
except Post.DoesNotExist:
raise status.HTTP_404_NOT_FOUND
def get(self, request, pk):
post = self.get_object(pk)
serializer = PostSerializer(post)
return Response(serializer.data)
def put(self, request, pk):
post = self.get_object(pk)
serializer = PostSerializer(post, 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):
post = self.get_object(pk)
post.delete()
return Response(status = status.HTTP_204_NO_CONTENT)
在上述代码中:
AuthorListCreateView
处理获取所有作者列表(GET
请求)和创建新作者(POST
请求)的逻辑。AuthorDetailView
处理获取单个作者详情(GET
请求)、更新作者信息(PUT
请求)和删除作者(DELETE
请求)的逻辑。PostListCreateView
和PostDetailView
与作者相关的视图类似,分别处理文章列表和单个文章的操作。
7. 配置 URL
接下来,我们需要将视图映射到相应的 URL。在 myproject/urls.py
文件中添加以下代码:
from django.contrib import admin
from django.urls import path, include
urlpatterns = [
path('admin/', admin.site.urls),
path('api/', include('api.urls')),
]
上述代码将所有以 api/
开头的 URL 都包含到 api
应用的 urls.py
文件中进行处理。
在 api
应用目录下创建一个新文件 urls.py
,并编写以下代码:
from django.urls import path
from. import views
urlpatterns = [
path('authors/', views.AuthorListCreateView.as_view(), name = 'author - list - create'),
path('authors/<int:pk>/', views.AuthorDetailView.as_view(), name = 'author - detail'),
path('posts/', views.PostListCreateView.as_view(), name = 'post - list - create'),
path('posts/<int:pk>/', views.PostDetailView.as_view(), name = 'post - detail'),
]
上述代码定义了四个 URL 模式:
/api/authors/
用于获取作者列表或创建新作者。/api/authors/<int:pk>/
用于获取、更新或删除特定作者,其中<int:pk>
是作者的主键。/api/posts/
和/api/posts/<int:pk>/
分别用于处理文章列表和单个文章的操作。
8. 配置 Django REST framework
打开 myproject/settings.py
文件,在 INSTALLED_APPS
列表中添加 'rest_framework'
:
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'api',
]
这样,Django 就知道要使用 djangorestframework
了。
9. 运行开发服务器
在项目根目录下运行以下命令启动开发服务器:
python manage.py runserver
服务器启动后,你可以通过浏览器或工具(如 Postman)访问 API。例如,访问 http://127.0.0.1:8000/api/authors/
可以获取作者列表,发送 POST
请求到该 URL 可以创建新作者。
10. 使用视图集和路由器简化代码
虽然前面的方法能够实现 RESTful API 的开发,但代码量相对较大。Django REST framework 提供了视图集(ViewSets)和路由器(Routers)来简化代码。
10.1 重写视图
首先,修改 api/views.py
文件,使用视图集:
from rest_framework.viewsets import ModelViewSet
from.models import Author, Post
from.serializers import AuthorSerializer, PostSerializer
class AuthorViewSet(ModelViewSet):
queryset = Author.objects.all()
serializer_class = AuthorSerializer
class PostViewSet(ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
ModelViewSet
类提供了默认的 list
(获取列表)、create
(创建)、retrieve
(获取单个对象)、update
(更新)和 destroy
(删除)等方法,我们只需要指定 queryset
和 serializer_class
即可。
10.2 配置路由器
修改 api/urls.py
文件,使用路由器:
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from. import views
router = DefaultRouter()
router.register('authors', views.AuthorViewSet, basename = 'author')
router.register('posts', views.PostViewSet, basename = 'post')
urlpatterns = [
path('', include(router.urls)),
]
DefaultRouter
会自动为视图集生成 URL 模式。register
方法用于注册视图集,第一个参数是 URL 前缀,第二个参数是视图集类,basename
用于生成 URL 名称。
这样,我们就通过视图集和路由器简化了 API 开发的代码,同时功能与之前手动编写视图和 URL 模式的方式是一样的。
11. 认证和权限
在实际应用中,我们通常需要对 API 进行认证和权限控制,以确保只有授权的用户能够访问和操作数据。
11.1 认证
Django REST framework 提供了多种认证方式,如基本认证、令牌认证等。以令牌认证为例,首先需要安装 djangorestframework - simplejwt
来生成和验证 JSON Web Tokens。运行以下命令进行安装:
pip install djangorestframework - simplejwt
然后在 myproject/settings.py
文件中配置认证方式:
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
)
}
生成令牌的视图已经由 djangorestframework - simplejwt
提供,我们只需要在 URL 中包含它们。在 myproject/urls.py
文件中添加以下代码:
from rest_framework_simplejwt.views import TokenObtainPairView, TokenRefreshView
urlpatterns = [
# 其他 URL 模式
path('api/token/', TokenObtainPairView.as_view(), name = 'token - obtain - pair'),
path('api/token/refresh/', TokenRefreshView.as_view(), name = 'token - refresh'),
]
用户可以通过发送用户名和密码到 /api/token/
来获取访问令牌(access token)和刷新令牌(refresh token),访问令牌用于认证 API 请求,刷新令牌用于获取新的访问令牌。
11.2 权限
权限控制决定了哪些用户可以对 API 执行哪些操作。例如,我们可以设置只有文章的作者才能更新或删除文章。在 api/views.py
文件中,导入权限模块并设置权限:
from rest_framework.permissions import IsAuthenticated, IsAuthenticatedOrReadOnly, DjangoModelPermissions
class PostViewSet(ModelViewSet):
queryset = Post.objects.all()
serializer_class = PostSerializer
permission_classes = [IsAuthenticatedOrReadOnly]
class AuthorViewSet(ModelViewSet):
queryset = Author.objects.all()
serializer_class = AuthorSerializer
permission_classes = [DjangoModelPermissions]
在上述代码中:
PostViewSet
使用IsAuthenticatedOrReadOnly
权限类,意味着已认证的用户可以进行所有操作(创建、更新、删除),未认证的用户只能进行读取操作。AuthorViewSet
使用DjangoModelPermissions
,它根据 Django 内置的权限系统来控制对Author
模型的操作。
12. 测试 API
测试是确保 API 功能正确性的重要步骤。Django REST framework 提供了方便的测试工具。在 api/tests.py
文件中编写以下测试代码:
from django.test import TestCase
from rest_framework.test import APIClient
from.models import Author, Post
from.serializers import AuthorSerializer, PostSerializer
class AuthorAPITest(TestCase):
def setUp(self):
self.client = APIClient()
self.author = Author.objects.create(name = 'Test Author', email = 'test@example.com')
def test_get_authors(self):
response = self.client.get('/api/authors/')
authors = Author.objects.all()
serializer = AuthorSerializer(authors, many = True)
self.assertEqual(response.data, serializer.data)
def test_create_author(self):
data = {
'name': 'New Author',
'email': 'new@example.com'
}
response = self.client.post('/api/authors/', data)
self.assertEqual(response.status_code, 201)
class PostAPITest(TestCase):
def setUp(self):
self.client = APIClient()
self.author = Author.objects.create(name = 'Test Author', email = 'test@example.com')
self.post = Post.objects.create(title = 'Test Post', content = 'This is a test post', author = self.author)
def test_get_posts(self):
response = self.client.get('/api/posts/')
posts = Post.objects.all()
serializer = PostSerializer(posts, many = True)
self.assertEqual(response.data, serializer.data)
def test_create_post(self):
data = {
'title': 'New Post',
'content': 'This is a new post',
'author': self.author.id
}
response = self.client.post('/api/posts/', data)
self.assertEqual(response.status_code, 201)
在上述代码中:
AuthorAPITest
类用于测试与作者相关的 API 端点,setUp
方法在每个测试方法执行前创建一个测试客户端和一个作者对象。test_get_authors
方法测试获取作者列表的 API 是否返回正确的数据。test_create_author
方法测试创建新作者的 API 是否正常工作。PostAPITest
类与AuthorAPITest
类似,用于测试与文章相关的 API 端点。
运行测试可以使用以下命令:
python manage.py test
通过这些测试,可以确保 API 的功能符合预期。
通过以上步骤,我们详细介绍了如何使用 Django 和 Django REST framework 进行 RESTful API 的开发,涵盖了从项目创建、模型定义、序列化器编写、视图创建、URL 配置到认证、权限和测试等各个方面。希望这篇文章能帮助你快速上手并开发出健壮的 RESTful API。