11-1 视图集和路由器-DRF视图集(ModelViewSet)与API后缀、路由器
目录:
- DRF视图集(ModelViewSet)
- API后缀
- 路由器
一、DRF视图集(ModelViewSet)
1.1、ModelViewSet源码介绍
之前我们已经学了类视图,但是感觉还是要写两视图,一个是Lits,另外一个是 Detail,虽然已经大大减轻了我们的代码量,DRF给我了提供了更加抽象的封装,叫做ModelViewSet。
from rest_framework.viewsets import ModelViewSet #导入ModelViewSet
#Ctrl + ModelViewSet 查看源码
class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet):
"""
A viewset that provides default `create()`, `retrieve()`, `update()`,
`partial_update()`, `destroy()` and `list()` actions.
"""
pass
关系如图:

1.2、模型
说明:新建app06,模型为Games
from django.db import models
class Game(models.Model):
name = models.CharField(verbose_name="游戏名", max_length=64)
status = models.IntegerField(verbose_name="状态")
def __str__(self):
return self.name
1.3、序列化
说明:序列化类,新建serializers.py
from rest_framework import serializers
from .models import Game
class GameSerializer(serializers.ModelSerializer):
class Meta:
model = Game
fields = "__all__"
1.4、视图
说明:既然4个都集成了,那我们是不是应该把两个类视图写成一个呐。如下:
from rest_framework.viewsets import ModelViewSet #导入视图集ModelViewSet from .models import Game from .serializers import GameSerializer class GameView(ModelViewSet): queryset = Game.objects.all() serializer_class = GameSerializer
1.5、路由
说明:我们需要在子路由中之明,你哪些视图用的是什么方法。下面是子路由,根级路由:path('api/', include('app06.urls'))
from django.urls import path
from app06 import views
game_list = views.GameView.as_view({
'get': 'list',
'post': 'create'
})
game_detail = views.GameView.as_view({
'get': 'retrieve',
'put': 'update',
'patch': 'partial_update',
'delete': 'destroy'
})
urlpatterns = [
path("game/", game_list, name="game-list"), # 获取或创建
path("game/<int:pk>/", game_detail, name="game-detail") # 查找、更新、删除
]
1.6、测试结果

二、API后缀
有的时候我们为了告诉人家,我们是api接口 会在接口的 最后面 加上 .json 或者 .api的方式去访问。那如何 给API 加后缀呐。我们需要在路由做操作:
from django.urls import path
from app06 import views
....
urlpatterns = [
.....
]
from rest_framework.urlpatterns import format_suffix_patterns #导入format_suffix_patterns
urlpatterns = format_suffix_patterns(urlpatterns, allowed=['json', 'api']) #给api加后缀
测试效果:
1、以.api结尾的效果:

2、以.json结尾的效果

在视图方法里面加个format参数:
def put(self, request, format=None, *args, **kwargs):
user = self.get_user(kwargs.get('id'))
serializer = UserSerializer(user, data=request.data, context={'request': request})
if serializer.is_valid():
serializer.save()
return Response(serializer.data)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
三、路由
当我们集成 modelViewset的时候,代码量是少了不少,但是路由变的麻烦起来了,我们写路由的时候,还要把List和Detail还要分开写,好烦啊。其实不用这样的,只需要我们可以通过Router类自动帮我们生成路由。
from django.urls import path, include
from app06 import views
from rest_framework.routers import DefaultRouter #导入默认路由
router = DefaultRouter() #定义对象
router.register('game', views.GameView) # 自动生成路由
urlpatterns = [
# path("game/", game_list, name="game-list"),
# path("game/<int:pk>/", game_detail, name="game-detail")
path('', include(router.urls)), #会自动生成像上面的两个路由
]
# 这边需要注释掉,因为默认帮你提供 .json和.api后缀
# from rest_framework.urlpatterns import format_suffix_patterns
#
# urlpatterns = format_suffix_patterns(urlpatterns, allowed=['json', 'api'])
测试结果跟上面是一样的。我就不测试啦。

浙公网安备 33010602011771号