MK
摩柯社区 - 一个极简的技术知识社区
AI 面试

Python使用Django进行RESTful API开发

2023-04-047.2k 阅读

1. 准备工作

在开始使用 Django 进行 RESTful API 开发之前,确保你已经安装了 Python 和 Django。如果还没有安装,可以按照以下步骤进行安装:

  1. 安装 Python:从 Python 官方网站(https://www.python.org/downloads/)下载并安装最新版本的 Python。安装过程中,记得勾选“Add Python to PATH”选项,以便在命令行中能够直接使用 Python 命令。
  2. 安装 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 字段设置为 AuthorSerializerread_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 请求)的逻辑。
  • PostListCreateViewPostDetailView 与作者相关的视图类似,分别处理文章列表和单个文章的操作。

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(删除)等方法,我们只需要指定 querysetserializer_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。