前言
视图集和路由器是 Django REST Framework 中的工具,可以加速 API 开发。 它们是视图和 URL 之上的附加抽象层。 主要好处是单个视图集可以替换多个相关视图。 路由器可以自动为开发人员生成 URL。 在具有许多端点的大型项目中,这意味着开发人员必须编写更少的代码。 可以说,与一长串的单个视图和 URL 相比,对于经验丰富的开发人员而言,与少量视图集和路由器组合相比,它更易于理解和推理。
在本章中,我们将向现有项目中添加两个新的 API 端点,并了解如何从视图和 URL 切换到视图集和路由器可以用更少的代码实现相同的功能。
用户终端
当前,我们的项目中具有以下 API 端点。 它们都以 api/v1/
开头,为简洁起见,未显示它们:
前两个端点是我们创建的,而 django-rest-auth 提供了另外五个端点。 现在让我们添加两个其他端点,以列出所有用户和单个用户。 这是许多 API 中的常见功能,它将使我们更清楚地理解为什么将我们的视图和 URL 重构为视图集和路由器是有意义的。
传统 Django 具有内置的 User 模型类,我们已经在上一篇文章中使用了该类进行身份验证。 因此,我们不需要创建新的数据库模型。 相反,我们只需要连接新的端点即可。 此过程始终涉及以下三个步骤:
- 新增模型序列化器
- 新增每个端点视图
- 新增每个端点的 URL 路由
从我们的序列化器开始。 我们需要导入 User 模型,然后创建一个使用它的 UserSerializer 类。 然后将其添加到我们现有的 posts/serializers.py
文件中。
# posts/serializers.py from django.contrib.auth import get_user_model # new from rest_framework import serializers from .models import Post class PostSerializer(serializers.ModelSerializer): class Meta: model = Post fields = ('id', 'author', 'title', 'body', 'created_at',) class UserSerializer(serializers.ModelSerializer): # new class Meta: model = get_user_model() fields = ('id', 'username',)
值得注意的是,虽然我们在这里使用 get_user_model 来引用 User 模型,但实际上在 Django 中有3种不同的方式来引用 User 模型。
通过使用 get_user_model ,我们确保我们引用的是正确的用户模型,无论是默认用户模型还是新 Django 项目中经常定义的自定义用户模型。
接下来,我们需要为每个端点定义视图。 首先将 UserSerializer 添加到导入列表中。 然后创建列出所有用户的 UserList 类和提供单个用户详细视图的 UserDetail 类。 就像我们的帖子视图一样,我们可以在此处使用 ListCreateAPIView 和 RetrieveUpdateDestroyAPIView。
对于每个端点,我们只需要只读或 GET 功能。 这意味着我们可以使用 ListAPIView 和 RetrieveUpdateDestroyAPIView 。 我们还需要通过 get_user_model 引用用户模型,以便将其导入第一行。
# posts/views.py from django.contrib.auth import get_user_model # new from rest_framework import generics from .models import Post from .permissions import IsAuthorOrReadOnly from .serializers import PostSerializer, UserSerializer # new class PostList(generics.ListCreateAPIView): 0 queryset = Post.objects.all() serializer_class = PostSerializer class PostDetail(generics.RetrieveUpdateDestroyAPIView): permission_classes = (IsAuthorOrReadOnly,) queryset = Post.objects.all() serializer_class = PostSerializer class UserList(generics.ListCreateAPIView): # new queryset = get_user_model().objects.all() serializer_class = UserSerializer class UserDetail(generics.RetrieveUpdateDestroyAPIView): # new queryset = get_user_model().objects.all() serializer_class = UserSerializer
如果您注意到,这里有很多重复。 Post 视图和 User 视图都具有完全相同的 queryset 和 serializer_class。
最后,我们有了 URL 路由。 确保导入新的 UserList 和 UserDetail 视图。 然后,我们可以为每个用户使用前缀 users/
。
# posts/urls.py from django.urls import path from .views import UserList, UserDetail, PostList, PostDetail # new urlpatterns = [ path('users/', UserList.as_view()), # new path('users/<int:pk>/', UserDetail.as_view()), # new path('', PostList.as_view()), path('<int:pk>/', PostDetail.as_view()), ]
我们完成了。 确保本地服务器仍在运行,并跳至可浏览的 API 以确认一切正常。
我们的用户列表端点位于 http://127.0.0.1:8000/api/v1/users/
状态代码为 200 OK ,表示一切正常。 我们可以看到三个现有用户。
每个用户的主键上都有一个用户详细信息终结点。 因此,我们的超级用户帐户位于:http://127.0.0.1:8000/api/v1/users/1/
。