首页 > 其他分享 >DRF的视图与路由集Routers

DRF的视图与路由集Routers

时间:2022-12-06 15:58:37浏览次数:42  
标签:get Routers self request 视图 序列化 serializer DRF

一 视图

Django REST framwork 提供的视图的主要作用:

  • 控制序列化器的执行(检验、保存、转换数据)

  • 控制数据库模型的操作

一 普通视图APIView

一 两个视图基类

1 APIView基本视图类

from rest_framework import status
from rest_framework.views import APIView
from .serializers import StudentModelSerializer, Student
from rest_framework.response import Response

"""
POST /students/   添加一个学生信息
GET  /students/   获取所有学生信息

GET    /students/<pk>/  获取一个学生信息
PUT    /students/<pk>/  更新一个学生信息
DELETE /students/<pk>/  删除一个学生信息

一个路由对应一个视图类,所以我们可以把5个API分成2个类来完成
"""


class StudentAPIView(APIView):
    def get(self,request):
        """获取所有学生信息"""
        # 1. 从数据库中读取学生列表信息
        instance_list = Student.objects.all()
        # 2. 实例化序列化器,获取序列化对象
        serializer = StudentModelSerializer(instance_list, many=True)
        # 3. 使用serializer.data实现对数据进行序列化成字典
        return Response(serializer.data)

    def post(self,request):
        """添加学生信息"""
        # 1. 获取客户端提交的数据,实例化序列化器,获取序列化对象
        serializer = StudentModelSerializer(data=request.data)
        # 2. 反序列化[验证数据、保存数据到数据库]
        serializer.is_valid(raise_exception=True)
        serializer.save()
        # 3. 返回新增的模型数据经过序列化提供给客户端
        return Response(serializer.data, status=status.HTTP_201_CREATED)


class StudentInfoAPIView(APIView):
    def get(self, request, pk):
        """获取一个学生信息"""
        # 1. 使用pk作为条件获取模型对象
        instance = Student.objects.get(pk=pk)
        # 2. 实例化序列化器对象
        serializer = StudentModelSerializer(instance)
        # 3. 序列化数据并返回结果
        return Response(serializer.data)

    def put(self,request, pk):
        """更新一个学生信息"""
        # 1. 使用pk作为条件获取模型对象
        instance = Student.objects.get(pk=pk)
        # 2.获取客户端提交的数据,实例化序列化器,获取序列化对象
        serializer = StudentModelSerializer(instance, request.data)
        # 3. 反序列化[验证数据、保存数据到数据库]
        serializer.is_valid(raise_exception=True)
        serializer.save()
        # 4. 返回更新后的模型数据经过序列化提供给客户端
        return Response(serializer.data)

    def delete(self, request, pk):
        """删除一个学生信息"""
        # 1. 根据PK值获取要删除的数据并删除
        Student.objects.filter(pk=pk).delete()
        # 2. 影响删除结构
        return Response(status=status.HTTP_204_NO_CONTENT)
视图代码

1.1 APIView是REST framework提供的所有视图类的基类,继承自Django的View父类。

rest_framework.views.APIView

1.2 APIView与View的不同之处在于:

- 传入到视图方法中的是REST framework的Request对象,而不是Django的HttpRequeset对象;

- 视图方法可以返回REST framework的Response对象,视图会为响应数据设置(renderer)符合前端期望要求的格式;

- 任何可以被APIException捕获到异常,都将会被APIView处理成合适格式的响应信息返回给客户端;

  django 的View中所有异常全部以HTML格式显示,不会返回json格式。

  drf的APIVIew或者APIView的子类会自动根据客户端的Accept进行错误信息的格式转换。

- 重新声明了一个新的as_view方法并在dispatch()进行路由分发前,会对请求的客户端进行身份认证、权限检查、流量控制。

APIView除了继承了View原有的属性方法意外,还新增了类属性:

- authentication_classes值是列表或元组,成员是身份认证类
- permissoin_classes值是列表或元组,成员是权限检查类
- throttle_classes值是列表或元祖,成员是流量控制类

在APIView中仍以常规的类视图定义方法来实现get() 、post() 或者其他请求方式的方法。

2 GenericAPIView通用视图类

from rest_framework.generics import GenericAPIView


"""
APIView中的api接口代码,除了部分涉及到调用模型和序列化器的代码以外,其他代码几乎都是固定写法。
所以,当我们将来针对增删查改的通用api接口编写时,完全可以基于原有的代码进行复用,
那么,drf也考虑到了这个问题,所以提供了一个GenericAPIView(通用视图类),让我们可以把接口中独特的代码单独提取出来作为类属性存在。
rest_framework.generics.GenericAPIView是APIView的子类,在APIView的基础上进行属性扩展提供了2个属性,4个方法,方便我们针对通用接口进行编写。
"""


class StudentGenericAPIView(GenericAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

    def get(self,request):
        """获取所有学生信息"""
        # 1. 从数据库中读取学生列表信息
        instance_list = self.get_queryset()
        # 2. 实例化序列化器,获取序列化对象
        # serializer = self.serializer_class(instance_list, many=True)
        serializer = self.get_serializer(instance_list, many=True)
        # 3. 使用serializer.data实现对数据进行序列化成字典
        return Response(serializer.data)

    def post(self,request):
        """添加学生信息"""
        # 1. 获取客户端提交的数据,实例化序列化器,获取序列化对象
        serializer = self.get_serializer(data=request.data)
        # 2. 反序列化[验证数据、保存数据到数据库]
        serializer.is_valid(raise_exception=True)
        serializer.save()
        # 3. 返回新增的模型数据经过序列化提供给客户端s1
        return Response(serializer.data, status=status.HTTP_201_CREATED)


class StudentInfoGenericAPIView(GenericAPIView):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

    def get(self, request, pk):
        """获取一个学生信息"""
        # 1. 使用pk作为条件获取模型对象
        instance = self.get_object()
        # 2. 实例化序列化器对象
        serializer = self.get_serializer(instance)
        # 3. 序列化数据并返回结果
        return Response(serializer.data)

    def put(self,request, pk):
        """更新一个学生信息"""
        # 1. 使用pk作为条件获取模型对象
        instance = self.get_object()
        # 2.获取客户端提交的数据,实例化序列化器,获取序列化对象
        serializer = self.get_serializer(instance, request.data)
        # 3. 反序列化[验证数据、保存数据到数据库]
        serializer.is_valid(raise_exception=True)
        serializer.save()
        # 4. 返回更新后的模型数据经过序列化提供给客户端
        return Response(serializer.data)

    def delete(self, request, pk):
        """删除一个学生信息"""
        # 1. 根据PK值获取要删除的数据并删除
        self.get_object().delete()
        # 2. 影响删除结构
        return Response(status=status.HTTP_204_NO_CONTENT)
视图,代码

2.1 通用视图类在继承了APIView的所有功能以外,还提供了几个属性和方法让我们可以把视图中独特的代码抽取出来作为类属性,让视图方法中的代码变得更加通用,方便把通用代码进行简写

rest_framework.generics.GenericAPIView

2.2 提供的关于序列化器使用的1个属性与2个方法

# 属性:
serializer_class=A序列化器 指明视图使用的序列化器类

# 方法:
get_serializer_class(self)

当出现一个视图类中调用多个序列化器时,那么可以通过条件判断在get_serializer_class方法中通过返回不同的序列化器类名就可以让视图方法执行不同的序列化器对象了。

get_serializer(self, args, *kwargs)

返回序列化器对象,主要用来提供给Mixin扩展类使用,如果我们在视图中想要获取序列化器对象,也可以直接调用此方法。

注意,该方法在提供序列化器对象的时候,会向序列化器对象的context属性补充三个数据:request、format、view,这三个数据对象可以在序列化器内部使用。
request 当前视图的请求对象

view 当前请求的类视图对象

format 当前请求期望返回的数据格式

2.3 提供的关于数据库查询的1个属性与2个方法

# 属性:
  - queryset指明使用的数据查询的结果集

# 方法:
  - get_queryset(self)
返回视图使用的查询集QuerySet,主要用来提供给Mixin扩展类使用,是列表视图与详情视图获取数据的基础,默认返回`queryset`属性,可以重写,当获取数据时需要设置一些查询条件,则可以重写如下,例如:
"""
def get_queryset(self):
    user = self.request.user
    return user.course_list.all()
"""
  - get_object(self)

返回详情视图所需的1个模型类数据对象,主要用来提供给Mixin扩展类使用。

在试图中可以调用该方法获取详情信息的模型类对象。

**若详情访问的模型类对象不存在,会返回404异常。**
该方法会默认使用APIView提供的check_object_permissions方法检查当前客户端是否有权限访问当前模型对象。
"""
# url(r'^books/(?P<pk>\d+)/$', views.BookDetailView.as_view()),
class BookDetailView(GenericAPIView):
    queryset = BookInfo.objects.all()
    serializer_class = BookInfoSerializer

    def get(self, request, pk):
        """获取一本书的信息"""
        book = self.get_object() # get_object()方法 本质上就是 self.queryset.get(pk=pk)
        serializer = self.get_serializer(book)  # 本质上 self.serializer_class(book)
        return Response(serializer.data)
"""
# 其他可以设置的属性
- pagination_class 指明分页控制类
- filter_backends 指明数据过滤控制后端,允许客户端通过地址栏传递过滤参数

二 五个视图扩展类

也叫混入类,作用:提供了几种后端视图(对数据资源进行增删改查)处理流程的实现,如果需要编写的视图属于这五种,则视图可以通过继承相应的扩展类来复用代码,减少自己编写的代码量

这五个扩展类需要搭配GenericAPIView通用视图基类,因为五个扩展类的实现需要调用GenericAPIView提供的序列化器与数据库查询的方法。

"""
通用视图类 + 模型扩展类 实现5个基本API接口
获取多条数据 GenericsAPIView+Mixins.ListModelMixin
添加一条数据 GenericsAPIView+Mixins.CreateModelMixin
"""
from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, \
    UpdateModelMixin, DestroyModelMixin


class StudentListAPIView(GenericAPIView, ListModelMixin, CreateModelMixin):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

    def get(self, request):
        """获取所有学生信息"""
        return self.list(request)

    def post(self, request):
        """添加学生信息"""
        return self.create(request)

"""
获取一条数据 GenericsAPIView+Mixins.RetrieveModelMixin
更新一条数据 GenericsAPIView+Mixins.UpdateModelMixin
删除一条数据 GenericsAPIView+Mixins.DestroyModelMixin
"""

class StudentRetrieveAPIView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

    def get(self,request, pk):
        """获取一个学生信息"""
        return self.retrieve(request, pk)

    def put(self,request, pk):
        """更新一个学生信息"""
        return self.update(request, pk)

    def delete(self,request, pk):
        """删除一个学生信息"""
        return self.destroy(request, pk)
视图代码

1 ListModelMixin

列表视图扩展类,提供list(request, *args, **kwargs)方法快速实现列表视图,返回200状态码。

该Mixin的list方法会对数据进行过滤和分页。

2 CreateModelMixin

创建视图扩展类,提供create(request, *args, **kwargs)方法快速实现创建资源的视图,成功返回201状态码。

如果序列化器对前端发送的数据验证失败,返回400错误。

3 RetrieveModelMixin

详情视图扩展类,提供retrieve(request, *args, **kwargs)方法,可以快速实现返回一个存在的数据对象。

如果存在,返回200, 否则返回404。

4 UpdateModelMixin

更新视图扩展类,提供update(request, *args, **kwargs)方法,可以快速实现更新一个存在的数据对象。

同时也提供partial_update(request, *args, **kwargs)方法,可以实现局部更新。

成功返回200,序列化器校验数据失败时,返回400错误。

5 DestroyModelMixin

删除视图扩展类,提供destroy(request, *args, **kwargs)方法,可以快速实现删除一个存在的数据对象。

成功返回204,不存在返回404。

三 九个视图子类

视图子类是django为了方便开发者快速提供基于不同http请求视图而提供的。

from django.views.generic import ListView,DetailView,CreateView,UpdateView,DeleteView

ListView:   列表视图,可以通过get请求访问,用于展示列表数据,内置了分页功能 
DetailView:详情视图,可以通过get请求访问,用于展示单个数据
CreateView:添加视图,可以通过get/post请求访问,用于添加单个数据,get方法展示添加数据表单,post方法接受并处理表单数据
UpdateView:更新视图,可以通过get/post请求访问,用于更新单个数据,get方法展示添加数据表单,post方法接受并处理表单数据
DeleteView:删除视图,可以通过get请求访问,用于删除单个数据

1 ListAPIView

提供了get视图方法,内部调用了模型扩展类的list方法

继承自:GenericAPIView、ListModelMixin

2 CreateAPIView

提供了post视图方法,内部调用了模型扩展类的create方法

继承自: GenericAPIView、CreateModelMixin

3 RetrieveAPIView

提供了get视图方法,内部调用了模型扩展类的retrieve方法

继承自: GenericAPIView、RetrieveModelMixin

4 DestroyAPIView

提供了delete视图方法,内部调用了模型扩展类的destroy方法

继承自:GenericAPIView、DestoryModelMixin

5 UpdateAPIView

提供了put和patch视图方法,内部调用了模型扩展类的update和partial_update方法

继承自:GenericAPIView、UpdateModelMixin

6 ListCreateAPIView

提供了get和post方法,内部调用了list和create方法

继承自:GenericAPIView、ListModelMixin、CreateModelMixin

7 RetrieveUpdateAPIView

提供 get、put、patch方法

继承自: GenericAPIView、RetrieveModelMixin、UpdateModelMixin

8 RetrieveDestroyAPIView

提供 get、delete方法

继承自:GenericAPIView、RetrieveModelMixin、DestroyModelMixin

9 RetrieveUpdateDestroyAPIView

提供 get、put、patch、delete方法

继承自:GenericAPIView、RetrieveModelMixin、UpdateModelMixin、DestroyModelMixin

二 视图集ViewSet

使用视图集ViewSet,可以将一系列视图相关的代码逻辑和相关的http请求动作封装到一个类中:

  • list() 提供一组数据

  • retrieve() 提供单个数据

  • create() 创建数据

  • update() 保存数据

  • destory() 删除数据

ViewSet视图集类不再限制视图方法名为get/post...等这种情况了,而是实现允许开发者根据自己的需要定义自定义视图方法名,例如 list() 或get_all()、create() 等,然后经过路由中使用http请求动作和这些视图方法名action进行绑定映射调用

视图集在使用as_view()方法时,设置字典参数允许我们将代表视图方法名与具体http请求进行绑定。

一 常用视图集父类

1 ViewSet

"""使用ViewSet基本视图集实现5个基本api接口"""
from rest_framework.viewsets import ViewSet


class StudentViewSet(ViewSet):
    def list(self,request):
        """获取多个数据"""
        # 1. 从数据库中读取模型列表信息
        instance_list = Student.objects.all()
        # 2. 实例化序列化器,获取序列化对象
        serializer = StudentModelSerializer(instance_list, many=True)
        # 3. 使用serializer.data实现对数据进行序列化成字典
        return Response(serializer.data)

    def create(self, request):
        """添加数据"""
        # 1. 获取客户端提交的数据,实例化序列化器,获取序列化对象
        serializer = StudentModelSerializer(data=request.data)
        # 2. 反序列化[验证数据、保存数据到数据库]
        serializer.is_valid(raise_exception=True)
        serializer.save()
        # 3. 返回新增的模型数据经过序列化提供给客户端
        return Response(serializer.data, status=status.HTTP_201_CREATED)

    def retrieve(self, request, pk):
        """获取一个学生信息"""
        # 1. 使用pk作为条件获取模型对象
        instance = Student.objects.get(pk=pk)
        # 2. 实例化序列化器对象
        serializer = StudentModelSerializer(instance)
        # 3. 序列化数据并返回结果
        return Response(serializer.data)

    def update(self,request, pk):
        """更新一个学生信息"""
        # 1. 使用pk作为条件获取模型对象
        instance = Student.objects.get(pk=pk)
        # 2.获取客户端提交的数据,实例化序列化器,获取序列化对象
        serializer = StudentModelSerializer(instance, request.data)
        # 3. 反序列化[验证数据、保存数据到数据库]
        serializer.is_valid(raise_exception=True)
        serializer.save()
        # 4. 返回更新后的模型数据经过序列化提供给客户端
        return Response(serializer.data)

    def destroy(self, request, pk):
        """删除一个学生信息"""
        # 1. 根据PK值获取要删除的数据并删除
        Student.objects.filter(pk=pk).delete()
        # 2. 影响删除结构
        return Response(status=status.HTTP_204_NO_CONTENT)
视图代码

路由设置

from django.urls import path,re_path
from . import views
urlpatterns = [
    # 代码省略。。。。。。
    # ViewSet
    # 视图集的路由注册格式
    # path("访问路径", views.视图集类名.as_view({"http请求方法名": "视图方法名", "http请求方法名": "视图方法名", ...})),
    path("students4/", views.StudentViewSet.as_view({"get": "list", "post": "create"})),
    re_path("^students4/(?P<pk>\d+)/$", views.StudentViewSet.as_view({
        "get": "retrieve",
        "put": "update",
        "delete": "destroy",
    })),

继承自APIView与ViewSetMixin,作用也与APIView基本类似,提供了身份认证、权限校验、流量管理等。ViewSet主要通过继承ViewSetMixin来实现在调用as_view()时传入字典{“http请求”:“视图方法”}的映射处理工作,如{'get':'list'},

在ViewSet中,没有提供任何动作action方法,需要我们自己实现action方法。

# 上面代码如果想要合并成一个视图类,实现一个视图类提供5个甚至更多的API接口,则需要继承视图集(ViewSet)为什么要继承视图集(ViewSet)?
1. 上面使用的视图类都是基于APIView实现的,而APIView基于django提供的View视图基类,
   而django的视图类View在内部实现时,dispatch方法中限制了当前视图必须采用get/post/put/delete/patch等http请求动作作为方法名,但是
   如果要实现5个api接口,必然要实现2个get请求,分别是获取多条数据与获取一条数据,一个类中肯定不存在同名的方法。
   
2. 5个接口api接口中,只有删除、获取、更新一条数据时需要地址栏传递ID,而添加一条数据与获取多条数据,实际上并不需要ID。
   所以,路由有决定我们要分开写5个接口。

# drf为了解决上面的2个问题,提供了视图集和路由集。
视图集就可以帮我们实现一个视图类响应多种重复的http请求
路由集就可以帮我们实现自动根据不同的视图方法来生成不同参数的路由地址。
from rest_framework.viewsets import ViewSet  # ViewSet是APIView的子类,是所有drf中的视图集的父类

GenericViewSet

"""
使用通用视图集类GenericViewSet实现接口中独特代码的分离
"""
from rest_framework.viewsets import GenericViewSet


class StudentGenericViewSet(GenericViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

    def list(self,request):
        """获取多个数据"""
        # 1. 从数据库中读取模型列表信息
        instance_list = self.get_queryset()
        # 2. 实例化序列化器,获取序列化对象
        serializer = self.get_serializer(instance_list, many=True)
        # 3. 使用serializer.data实现对数据进行序列化成字典
        return Response(serializer.data)

    def create(self, request):
        """添加数据"""
        # 1. 获取客户端提交的数据,实例化序列化器,获取序列化对象
        serializer = self.get_serializer(data=request.data)
        # 2. 反序列化[验证数据、保存数据到数据库]
        serializer.is_valid(raise_exception=True)
        serializer.save()
        # 3. 返回新增的模型数据经过序列化提供给客户端
        return Response(serializer.data, status=status.HTTP_201_CREATED)

    def retrieve(self, request, pk):
        """获取一个数据"""
        # 1. 使用pk作为条件获取模型对象
        instance = self.get_object()
        # 2. 实例化序列化器对象
        serializer = self.get_serializer(instance)
        # 3. 序列化数据并返回结果
        return Response(serializer.data)

    def update(self,request, pk):
        """更新一个数据"""
        # 1. 使用pk作为条件获取模型对象
        instance = self.get_object()
        # 2.获取客户端提交的数据,实例化序列化器,获取序列化对象
        serializer = self.get_serializer(instance, request.data)
        # 3. 反序列化[验证数据、保存数据到数据库]
        serializer.is_valid(raise_exception=True)
        serializer.save()
        # 4. 返回更新后的模型数据经过序列化提供给客户端
        return Response(serializer.data)

    def destroy(self, request, pk):
        """删除一个数据"""
        # 1. 根据PK值获取要删除的数据并删除
        self.get_object().delete()
        # 2. 影响删除结构
        return Response(status=status.HTTP_204_NO_CONTENT)
视图代码

路由设置

from django.urls import path,re_path
from . import views
urlpatterns = [
。。
    # GenericViewSet
    path("students5/", views.StudentGenericViewSet.as_view({"get": "list", "post": "create"})),
    re_path("^students5/(?P<pk>\d+)/$", views.StudentGenericViewSet.as_view({
        "get": "retrieve",
        "put": "update",
        "delete": "destroy",
    })),
]

继承自GenericAPIView和ViewSetMixin,作用让视图集的视图代码变得更加通用,抽离独特代码作为视图类的属性。

使用ViewSet通常并不方便,因为list、retrieve、create、update、destory等方法都需要自己编写,而这些方法与前面讲过的Mixin扩展类提供的方法同名,所以我们可以通过继承Mixin扩展类来复用这些方法而无需自己编写。但是Mixin扩展类依赖与GenericAPIView,所以还需要继承GenericAPIView

GenericViewSet就帮助我们完成了这样的继承工作,继承自GenericAPIViewViewSetMixin,在实现了调用as_view()时传入字典(如{'get':'list'})的映射处理工作的同时,还提供了GenericAPIView提供的基础方法,可以直接搭配Mixin扩展类使用。

3 ModelViewSet

视图代码

"""
ModelViewSet = GenericViewSet + ListModelMixin + CreateModelMixin+
               RetrieveModelMixin + UpdateModelMixin + DestroyModelMixin
"""
from rest_framework.viewsets import ModelViewSet
class StudentModelViewSet(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

路由代码

    # ModelViewSet 模型视图集
    path("students7/", views.StudentModelViewSet.as_view({"get": "list", "post": "create"})),
    re_path("^students7/(?P<pk>\d+)/$", views.StudentModelViewSet.as_view({
        "get": "retrieve",
        "put": "update",
        "delete": "destroy",
    })),

继承自GenericViewSet,同时包括了ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin。

4 ReadOnlyModelViewSet

继承自GenericViewSet,同时包括了ListModelMixin、RetrieveModelMixin。

视图代码

"""
ReadOnlyModelViewSet = RetrieveModelMixin + ListModelMixin + GenericViewSet
"""
from rest_framework.viewsets import ReadOnlyModelViewSet


class StudentReadOnlyModelViewSet(ReadOnlyModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

路由代码

    # ReadOnlyModelViewSet  只读视图集
    path("students8/", views.StudentReadOnlyModelViewSet.as_view({"get": "list"})),
    re_path("^students8/(?P<pk>\d+)/$", views.StudentReadOnlyModelViewSet.as_view({"get": "retrieve"})),
]

二 路由集Routers

对于视图集ViewSet,我们除了可以自己手动指明请求方式与视图方法之间的对应关系外,还可以使用Routers来帮助我们快速实现路由信息。如果是非视图集,不需要使用路由集routers。

REST framework提供了两个router类,使用方式一致的。结果多一个或少一个根目录url地址的问题而已。

  • SimpleRouter 线上运营项目

  • DefaultRouter 本地开发,项目上线前

一 使用方法

1 创建router对象,并注册视图集。

demo/urls.py,代码:

"""使用路由集给视图集生成url路由"""
from rest_framework.routers import DefaultRouter, SimpleRouter

# 实例化路由对象
router = SimpleRouter()
# 注册视图集[每次注册一个视图集类,就需要调用register]
router.register("students9", views.StuModelViewSet, basename="student9")
router.register("students10", views.StuModelViewSet, basename="students10")

# 所有被注册的实体集生成的路由信息,全部会被集中到router.urls路由列表中,所以我们要把urls拼接到urlpatterns
urlpatterns += router.urls

参数说明

register(prefix, viewset, basename)

  • prefix 该视图集的路由前缀

  • viewset 视图集

  • basename 路由别名的前缀

2 把路由对象生成的视图集的路由列表添加到django的路由中,可以有两种方式:

方式1

urlpatterns = [
    ...
]

urlpatterns += router.urls

方式2

from django.urls import include,re_path
urlpatterns = [
    ...
    path("", include(router.urls)) #不能加“”,会被认为字符串
]

二 视图集中附加action的声明

在视图集中,如果想要让Router自动帮助我们为自定义视图方法生成对应路由信息,需要使用rest_framework.decorators.action装饰器。action装饰器可以让开发者在视图中绑定要路由集生成的url地址

action装饰器可以接收两个参数:

  • methods: 声明该action对应的请求方式,列表参数

  • detail: 声明该action的路径是否为单一资源,也就是使用生成附带pk值的url路径

  • True 表示路径格式是<prefix>/<pk>/<url_path>/

    • False 表示路径格式是<prefix>/<url_path>/

  • url_path:声明该action的路由尾缀。默认就是视图方法名

视图代码

from rest_framework.viewsets import ModelViewSet
from rest_framework.decorators import action


class StuModelViewSet(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

    # @action(methods=["GET", "POST"], detail=False, url_path="abc")
    @action(methods=["GET", "POST"], detail=False)
    def login(self, request):
        print(self.action)  # 获取当前视图方法名
        return Response("用户登录")

    @action(methods=["GET"], detail=True)
    def logout(self,request, pk):  # 当action装饰的参数detail值为True时,表示当前视图必须接收一个pk参数
        return Response("注销登录")

由路由器自动为此视图集自定义action方法形成的路由会是如下内容

url: ^students9/login/$                                   basename: students9-login
url: ^students9/(?P<pk>[^/.]+)/logout/$       basename: students9-logout

 

 

标签:get,Routers,self,request,视图,序列化,serializer,DRF
From: https://www.cnblogs.com/daminghuahua/p/16954830.html

相关文章

  • 记录一次物化视图解决视图查询慢问题
    涉及一个视图优化,记录如下,会有相应时间的数据延迟。CREATEMATERIALIZEDVIEWPU_VIEW_STOREREQBUILDIMMEDIATEREFRESHFORCEONDEMANDSTARTWITHSYSDATENEXTSY......
  • 视图
         ......
  • Rup架构视图
    RUP中有四种软件视图,这里复习一下,并根据资料整理一下。.软件的质量特性分为功能性需求和非功能性需求。功能需求就是"软件有什么用,软件需要做什么"......
  • Flutter 陈航 09-视图渲染 三棵树 Widget
    本文地址目录目录目录09|Widget,构建Flutter界面的基石视图渲染过程WidgetElementRenderObjectRenderObjectWidget介绍Element的创建RenderObject的创建与更新案......
  • MySQL进阶实战6,缓存表、视图、计数器表
    一、缓存表和汇总表有时提升性能最好的方法是在同一张表中保存衍生的冗余数据,有时候还需要创建一张完全独立的汇总表或缓存表。缓存表用来存储那些获取很简单,但速度较慢......
  • drf-解析器
    当请求过来时,解释器会根据content-type字段,选择相应的解释器,然后并将数据封装的request.data中。一般我们都是直接采用rest里面内置的解析器,无需自己定义REST_FRAMEWORK......
  • DRF-视图
    DRF视图类中除了APIView类,还有一个GenericAPIView类。GenericAPIView类主要给我们提供了2个属性,3个方法。属性:queryset:要序列化的数据serializer_class:序列化类 方法......
  • mysql高阶语句+视图
    一,高阶语句1.select:显示表格中一个或数个栏位的所有资料格式:SELECT"栏位"FROM"表名";2.where:条件查询格式:SELECT"栏位"FROM"表名"WHERE"条件";嵌套/多条件,......
  • 报名啦!一起学习《多视图几何》、深度学习SLAM、GTSAM库、DSO、SVO Pro
    以下内容来自从零开始机器人SLAM知识星球每日更新内容点击领取学习资料→机器人SLAM学习资料大礼包原文链接:【https://mp.weixin.qq.com/s/BgWuX86veLs3mth0gANY5g】......
  • DRF-频率限制
    DRF之权限和频率限制 一、权限权限可以限制用户对视图的访问和对具体数据对象的访问。在执行视图的dispatch方法前,会先进行视图访问权限的判断在通过get_object获......