前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >DRF 视图组件

DRF 视图组件

作者头像
HammerZe
发布2022-05-09 18:29:49
9190
发布2022-05-09 18:29:49
举报
文章被收录于专栏:Hammer随笔

目录

DRF 视图组件

DRF框架提供了很多通用的视图基类与扩展类,上篇使用的APIView是比较偏Base的,视图的使用更加简化了代码,这里介绍一下其他视图的用法

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

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

先来看看这其中的人情世故:两个视图基本类,五个扩展类,九个视图子类,视图集方法,视图集··

视图组件大纲

两个视图基本类

导入

代码语言:javascript
复制
from rest_framework.views import APIView
from rest_framework.generics import GenericAPIView
  • APIView:DRF最顶层视图类
  • GenericAPIView:DRF通用视图类

五个扩展类

扩展类不是视图类,没有集成APIView,需要配合GenericAPIView使用,因为五个扩展类的实现需要调用GenericAPIView提供的序列化器与数据库查询的方法 主要是用来对数据进行增删改查

导入

代码语言:javascript
复制
from rest_framework.mixins import CreateModelMixin,ListModelMixin,DestroyModelMixin,RetrieveModelMixin,UpdateModelMixin
  • CreateModelMixin
  • ListModelMixin
  • DestroyModelMixin
  • RetrieveModelMixin
  • UpdateModelMixin

九个子类视图

导入

代码语言:javascript
复制
from rest_framework.generics import  CreateAPIView,ListAPIView,DestroyAPIView,RetrieveAPIView,UpdateAPIView,ListCreateAPIView,RetrieveUpdateAPIView,RetrieveUpdateDestroyAPIView,RetrieveDestroyAPIView

视图子类其实可以理解为GenericAPIView通用视图类和Mixin扩展类的排列组合组成的,底层事通过封装和继承来写

视图集

导入

代码语言:javascript
复制
from rest_framework.viewsets import ModelViewSet,ReadOnlyModelViewSet,ViewSet,GenericViewSet,ViewSetMixin

常用视图集父类

  • ModelViewSet:继承自GenericViewSet,同时包括了ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin。
  • ReadOnlyModelViewSet:继承自GenericViewSet,同时包括了ListModelMixin、RetrieveModelMixin。
  • ViewSet:继承自APIView与ViewSetMixin,作用也与APIView基本类似,提供了身份认证、权限校验、流量管理等。ViewSet主要通过继承ViewSetMixin来实现在调用as_view()时传入字典({'get':'list'})的映射处理工作。
代码语言:txt
复制
- 在ViewSet中,没有提供任何动作action方法,需要我们自己实现action方法。GenericViewSet:使用ViewSet通常并不方便,因为
代码语言:txt
复制
- GenericViewSet就帮助我们完成了这样的继承工作,继承自GenericAPIView与`ViewSetMixin,在实现了调用as_view()时传入字典(如`{`'get'`:`'list'`}`)的映射处理工作的同时,还提供了GenericAPIView提供的基础方法,可以直接搭配Mixin扩展类使用。

魔法类

  • ViewSetMixin:控制自动生成路由

一览表

DRF中视图的“七十二变”

第一层是继承APIView写,第二层基于基于GenericAPIView写,第三层基于GenericAPIView+五个扩展类写,第四层通过九个视图子类来写,第五层是通过ViewSet写

ps:第几层是我意淫出来的词不要介意~,一层更比一层牛,欲练此功必先自宫!!!

第一层:基于APIview的五个接口

代码语言:javascript
复制
class BookView(APIView):
    def get(self, requets):
        # 序列化
        book_list = models.Book.objects.all()
        # 序列化多条数据many=True
        ser = serializer.BookSerializer(instance=book_list, many=True)
        return Response(ser.data)

    def post(self, request):
        # 获取反序列化数据
        ser = serializer.BookSerializer(data=request.data)
        if ser.is_valid():
            # 校验通过存入数据库,不需要重写create方法了
            ser.save()
            return Response({'code': 100, 'msg': '新增成功', 'data': ser.data})
        # 校验失败
        return Response({'code': 101, 'msg': '校验未通过', 'error': ser.errors})


class BookViewDetail(APIView):
    def get(self, request, pk):
        book = models.Book.objects.filter(pk=pk).first()
        ser = serializer.BookSerializer(instance=book)
        return Response(ser.data)

    def put(self, request, pk):
        book = models.Book.objects.filter(pk=pk).first()
        # 修改,instance和data都要传
        ser = serializer.BookSerializer(instance=book, data=request.data)
        if ser.is_valid():
            # 校验通过修改,不需要重写update
            ser.save()
            return Response({'code:': 100, 'msg': '修改成功', 'data': ser.data})
        # 校验不通过
        return Response({'code:': 102, 'msg': '校验未通过,修改失败', 'error': ser.errors})

    def delete(self, request, pk):
        models.Book.objects.filter(pk=pk).delete()
        return Response({'code': 100, 'msg': '删除成功'})

第一层五个接口demo

ModelSerializer序列化器实战 - HammerZe - 博客园 (cnblogs.com)

第二层:基于GenericAPIView的五个接口

常用类属性:

代码语言:javascript
复制
-GenericAPIView   继承了APIView,封装了一些属性和方法,跟数据库打交道
  	-queryset = None # 指定序列化集
    -serializer_class = None  # 指定序列化类
    -lookup_field = 'pk'  # 查询单条,分组分出来的参数,转换器对象参数的名字
    -filter_backends   # 过滤排序功能会用它
    -pagination_class  # 分页功能
    
    -get_queryset()  # 获取要序列化的数据,后期可能会重写
    -get_object()    # 通过lookup_field查询的
    -get_serializer()  # 使用它序列化
    -get_serializer_class() # 返回序列化类 ,后期可能重写
    
    
    
demo:
# 指定序列化集
queryset = models.Book.objects.all()
# 指定序列化类
serializer_class = serializer.BookSerializer

第二层五个接口demo

代码语言:javascript
复制
from rest_framework.response import Response


from app01 import models
from app01 import serializer
from rest_framework.generics import GenericAPIView
# 书视图类
class BookView(GenericAPIView):
    # 指定序列化集
    queryset = models.Book.objects.all()
    # 指定序列化类
    serializer_class = serializer.BookSerializer
    def get(self, requets):
        # obj = self.queryset()
        obj = self.get_queryset() # 等同于上面
        # ser = self.get_serializer_class()(instance=obj,many=True)
        ser = self.get_serializer(instance=obj,many=True) # 等同于上面
        return Response(ser.data)

    def post(self, request):
        # 获取反序列化数据
        # ser = serializer.BookSerializer(data=request.data)
        ser = self.get_serializer(data = request.data)
        if ser.is_valid():
            # 校验通过存入数据库,不需要重写create方法了
            ser.save()
            return Response({'code': 100, 'msg': '新增成功', 'data': ser.data})
        # 校验失败
        return Response({'code': 101, 'msg': '校验未通过', 'error': ser.errors})


class BookViewDetail(GenericAPIView):
    # 指定序列化集
    queryset = models.Book.objects.all()
    # 指定序列化类
    serializer_class = serializer.BookSerializer
    def get(self, request, pk):
        # book = models.Book.objects.filter(pk=pk).first()
        book = self.get_object() # 根据pk拿到单个对象
        # ser = serializer.BookSerializer(instance=book)
        ser = self.get_serializer(instance=book)
        return Response(ser.data)

    def put(self, request, pk):
        # book = models.Book.objects.filter(pk=pk).first()
        book = self.get_object()
        # 修改,instance和data都要传
        # ser = serializer.BookSerializer(instance=book, data=request.data)
        ser = self.get_serializer(instance=book,data=request.data)
        if ser.is_valid():
            # 校验通过修改,不需要重写update
            ser.save()
            return Response({'code:': 100, 'msg': '修改成功', 'data': ser.data})
        # 校验不通过
        return Response({'code:': 102, 'msg': '校验未通过,修改失败', 'error': ser.errors})

    def delete(self, request, pk):
        # models.Book.objects.filter(pk=pk).delete()
        self.get_object().delete()
        return Response({'code': 100, 'msg': '删除成功'})

路由

代码语言:javascript
复制
path('books/', views.BookView.as_view()),
path('books/<int:pk>', views.BookViewDetail.as_view())

总结:到第二层只需修改querysetserializer_class类属性即可,其余都不需要修改

注意:虽然pk没有在orm语句中过滤使用,但是路由分组要用,所以不能删,或者写成*args **kwargs接收多余的参数,且路由转换器必须写成pk

代码语言:javascript
复制
# 源码
lookup_field = 'pk'
lookup_url_kwarg = None

get_queryset()方法可以重写,如果我们需要在一个视图类内操作另外表模型,来指定序列化的数据

代码语言:javascript
复制
class BookViewDetail(GenericAPIView):
    queryset = models.Book.objects.all()
    ···
    '''
    指定序列化数据的格式:
    self.queryset()
    self.get_queryset() # 等同于上面
    queryset = models.Book.objects.all()
    '''
	# 可以重写get_queryset方法在book视图类里操作作者模型
    def get_queryset(self,request):
        if self.request.path == '/user'
        return Author.objects.all()
    ···
    # 这样序列化的数据就不一样了,根据不同的条件序列化不同的数据
    
    '''当然还可以通过重写get_serializer_class来返回其他序列化器类'''

第三层:基于GenericAPIView+五个视图扩展类写

五个视图扩展类:from rest_framework.mixins import CreateModelMixin,ListModelMixin,DestroyModelMixin,RetrieveModelMixin,UpdateModelMixin

通过GenericAPIView+视图扩展类来使得代码更简单,一个接口对应一个扩展类,注意扩展类不是视图类

  • ListModelMixin:获取所有API,对应list()方法
  • CreateModelMixin:新增一条API,对应create()方法
  • UpdateModelMixin:修改一条API,对应update()方法
  • RetrieveModelMixin:获取一条API,对应retrieve()方法
  • DestroyModelMixin:删除一条API,对应destroy()方法

注意:CreateModelMixin扩展类提供了更高级的方法,可以通过重写来校验数据存入

代码语言:javascript
复制
    def perform_create(self, serializer):
        serializer.save()

第三层五个接口demo

代码语言:javascript
复制
from app01 import models
from app01 import serializer
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import CreateModelMixin,ListModelMixin,DestroyModelMixin,RetrieveModelMixin,UpdateModelMixin

# 获取所有和新增API
class BookView(ListModelMixin,CreateModelMixin,GenericAPIView):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookSerializer
    def get(self, request):
       return super().list(request)

    def post(self, request):
        return super().create(request)

# 获取删除修改单个API
class BookViewDetail(UpdateModelMixin,RetrieveModelMixin,DestroyModelMixin,GenericAPIView):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookSerializer
    def get(self, request, *args,**kwargs):
        return super().retrieve(request, *args,**kwargs)

    def put(self, request, *args,**kwargs):
        return super().update(request, *args,**kwargs)

    def delete(self, request, *args,**kwargs):
        return super().destroy(request, *args,**kwargs)

总结

通过进一次封装+继承代码也变得越来越少了

GenericAPIView速写五个接口demo

模型

代码语言:javascript
复制
from django.db import models


# Create your models here.

# build four model tables

class Book(models.Model):
    name = models.CharField(max_length=32)
    price = models.DecimalField(decimal_places=2, max_digits=5)
    publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
    authors = models.ManyToManyField(to='Author')
    def __str__(self):
        return self.name

    # 自定制字段
    @property
    def publish_detail(self):
        return {'name': self.publish.name, 'addr': self.publish.city}


    @property
    def author_list(self):
        l = []
        print(self.authors.all()) # <QuerySet [<Author: Author object (1)>, <Author: Author object (2)>]>

        for author in self.authors.all():
            print(author.author_detail) # AuthorDetail object (1)
            l.append({'name': author.name, 'age': author.age, 'addr': author.author_detail.addr})
        return l


class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    author_detail = models.OneToOneField(to='AuthorDetail', on_delete=models.CASCADE)

    def __str__(self):
        return self.name

    @property
    def authordetail_info(self):
        return {'phone':self.author_detail.telephone,'addr':self.author_detail.addr}


class AuthorDetail(models.Model):
    telephone = models.BigIntegerField()
    addr = models.CharField(max_length=64)


class Publish(models.Model):
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)
    email = models.EmailField()

序列化器

代码语言:javascript
复制
from django.db import models


# Create your models here.

# build four model tables

class Book(models.Model):
    name = models.CharField(max_length=32)
    price = models.DecimalField(decimal_places=2, max_digits=5)
    publish = models.ForeignKey(to='Publish', on_delete=models.CASCADE)
    authors = models.ManyToManyField(to='Author')
    def __str__(self):
        return self.name

    # 自定制字段
    @property
    def publish_detail(self):
        return {'name': self.publish.name, 'addr': self.publish.city}


    @property
    def author_list(self):
        l = []
        print(self.authors.all()) # <QuerySet [<Author: Author object (1)>, <Author: Author object (2)>]>

        for author in self.authors.all():
            print(author.author_detail) # AuthorDetail object (1)
            l.append({'name': author.name, 'age': author.age, 'addr': author.author_detail.addr})
        return l


class Author(models.Model):
    name = models.CharField(max_length=32)
    age = models.IntegerField()
    author_detail = models.OneToOneField(to='AuthorDetail', on_delete=models.CASCADE)

    def __str__(self):
        return self.name

    @property
    def authordetail_info(self):
        return {'phone':self.author_detail.telephone,'addr':self.author_detail.addr}


class AuthorDetail(models.Model):
    telephone = models.BigIntegerField()
    addr = models.CharField(max_length=64)


class Publish(models.Model):
    name = models.CharField(max_length=32)
    city = models.CharField(max_length=32)
    email = models.EmailField()

视图

代码语言:javascript
复制
from rest_framework.generics import GenericAPIView
from rest_framework.mixins import ListModelMixin, CreateModelMixin, DestroyModelMixin, RetrieveModelMixin, \
    UpdateModelMixin

from app01 import models
from app01 import serializer


# 书视图类
class BookView(ListModelMixin, CreateModelMixin, GenericAPIView):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookSerializer

    def get(self, request):
        return super().list(request)

    def post(self, request):
        return super().create(request)


class BookViewDetail(RetrieveModelMixin, DestroyModelMixin, UpdateModelMixin, GenericAPIView):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookSerializer

    def get(self, request, *args, **kwargs):
        return super().retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return super().update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return super().destroy(request, *args, **kwargs)


# 作者
class AuthorView(ListModelMixin, CreateModelMixin, GenericAPIView):
    queryset = models.Author.objects.all()
    serializer_class = serializer.AuthorSerializer

    def get(self, request):
        return super().list(request)

    def post(self, request):
        return super().create(request)


class AuthorViewDetail(RetrieveModelMixin, DestroyModelMixin, UpdateModelMixin, GenericAPIView):
    queryset = models.Author.objects.all()
    serializer_class = serializer.AuthorSerializer

    def get(self, request, *args, **kwargs):
        return super().retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return super().update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return super().destroy(request, *args, **kwargs)


# 作者详情

class AuthorDetailView(ListModelMixin, CreateModelMixin, GenericAPIView):
    queryset = models.AuthorDetail.objects.all()
    serializer_class = serializer.AuthorDetailSerializer

    def get(self, request):
        return super().list(request)

    def post(self, request):
        return super().create(request)


class OneAuthorViewDetail(RetrieveModelMixin, DestroyModelMixin, UpdateModelMixin, GenericAPIView):
    queryset = models.AuthorDetail.objects.all()
    serializer_class = serializer.AuthorDetailSerializer

    def get(self, request, *args, **kwargs):
        return super().retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return super().update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return super().destroy(request, *args, **kwargs)


# 出版社
class PublishView(ListModelMixin, CreateModelMixin, GenericAPIView):
    queryset = models.Publish.objects.all()
    serializer_class = serializer.PublishSerializer

    def get(self, request):
        return super().list(request)

    def post(self, request):
        return super().create(request)


class PublishViewDetail(RetrieveModelMixin, DestroyModelMixin, UpdateModelMixin, GenericAPIView):
    queryset = models.Publish.objects.all()
    serializer_class = serializer.PublishSerializer

    def get(self, request, *args, **kwargs):
        return super().retrieve(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        return super().update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return super().destroy(request, *args, **kwargs)

路由

代码语言:javascript
复制
from django.contrib import admin
from django.urls import path

from app01 import views

urlpatterns = [
    path('admin/', admin.site.urls),
    # 书
    path('books/', views.BookView.as_view()),
    path('books/<int:pk>', views.BookViewDetail.as_view()),

    # 作者
    path('authors/', views.AuthorView.as_view()),
    path('authors/<int:pk>', views.AuthorViewDetail.as_view()),

    # 作者详情
    path('authorsdetail/', views.AuthorDetailView.as_view()),
    path('authorsdetail/<int:pk>', views.OneAuthorViewDetail.as_view()),

    # 出版社
    path('publish/', views.PublishView.as_view()),
    path('publish/<int:pk>', views.PublishViewDetail.as_view()),
]

Postman以及测完,请放心使用~

第四层:GenericAPIView+九个视图子类写五个接口

导入视图子类from rest_framework.generics import CreateAPIView,ListAPIView,DestroyAPIView,RetrieveAPIView,UpdateAPIView,ListCreateAPIView,RetrieveUpdateAPIView,RetrieveUpdateDestroyAPIView,RetrieveDestroyAPIView

使用哪个继承哪个就可以了,具体可以看继承的父类里有什么方法不需要刻意去记

代码语言:javascript
复制
from rest_framework.generics import  CreateAPIView,ListAPIView,DestroyAPIView,RetrieveAPIView,UpdateAPIView,ListCreateAPIView,RetrieveUpdateAPIView,RetrieveUpdateDestroyAPIView,RetrieveDestroyAPIView

# 1、查询所有,新增API
class BookView(ListCreateAPIView):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookSerializer
# 2、新增接口
class BookView(CreateAPIView):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookSerializer
# 3、查询接口
class BookView(ListAPIView):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookSerializer

# 4、查询单个,修改一个,删除一个接口
class BookViewDetail(RetrieveUpdateDestroyAPIView):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookSerializer

# 5、查询单个接口
class BookViewDetail(RetrieveAPIView):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookSerializer

# 6、修改单个接口
class BookViewDetail(UpdateAPIView):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookSerializer

# 7、删除单个接口
class BookViewDetail(DestroyAPIView):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookSerializer

# 8、查询单个、修改接口
class BookViewDetail(RetrieveUpdateAPIView):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookSerializer


# 9、查询单个、删除接口
class BookViewDetail(RetrieveDestroyAPIView):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookSerializer

'''上述共九个视图子类,九九归一剑诀~'''

# 更新和删除接口自己整合
class BookViewDetail(UpdateAPIView,DestroyAPIView):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookSerializer

第四层快速写五个接口demo

代码语言:javascript
复制
from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView

from app01 import models
from app01 import serializer

class BookView(ListCreateAPIView):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookSerializer

class BookViewDetail(RetrieveUpdateDestroyAPIView):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookSerializer
'''其余的和第三层一样'''

第五层:基于ViewSet写五个接口

视图集导入from rest_framework.viewsets import ModelViewSet,ReadOnlyModelViewSet,ViewSet,GenericViewSet,ViewSetMixin

路由导入from rest_framework.routers import SimpleRouter,DefaultRouter

基于ViewSet视图集写,需要我们配置路由

两种不同的路由

第五层基于ModelViewSet视图集写五个接口demo

views.py

代码语言:javascript
复制
from rest_framework.viewsets import ModelViewSet,ReadOnlyModelViewSet,ViewSet,GenericViewSet,ViewSetMixin
class BookView(ModelViewSet):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookSerializer

urls.py

代码语言:javascript
复制
from django.contrib import admin
from django.urls import path, include
from rest_framework.routers import SimpleRouter

from app01 import views

router = SimpleRouter()
router.register('books', views.BookView, 'books')

urlpatterns = [
    path('admin/', admin.site.urls),
    path('api/v1/',include(router.urls)),
]

ps:剩下的都一样~

ReadOnlyModelViewSet视图集

继承该ReadOnlyModelViewSet视图集的作用是只读,只做查询,修改删除等操作不允许

代码语言:javascript
复制
from rest_framework.viewsets import ModelViewSet,ReadOnlyModelViewSet,ViewSet,GenericViewSet,ViewSetMixin
class BookView(ReadOnlyModelViewSet):
    queryset = models.Book.objects.all()
    serializer_class = serializer.BookSerializer

两个视图集总结

  • ModelViewSet可以写五个接口,而ReadOnlyModelViewSet只能写两个接口

本质

  • ModelViewSet继承了五个视图扩展类+GenericViewSet,GenericViewSet继承了ViewSetMixin+GenericAPIView PS:ViewSetMixin控制了路由写法
  • ReadOnlyModelViewSet继承了RetrieveModelMixin+ListModelMixin+GenericViewSet

其他视图集

ViewSet

ViewSet = ViewSetMixin+APIView

代码语言:javascript
复制
class ViewSet(ViewSetMixin, views.APIView):
    """
    The base ViewSet class does not provide any actions by default.
    """
    pass
GenericViewSet

GenericViewSet = ViewSetMixin+GenericAPIView

代码语言:javascript
复制
class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
    """
    The GenericViewSet class does not provide any actions by default,
    but does include the base set of generic view behavior, such as
    the `get_object` and `get_queryset` methods.
    """
    pass
ViewSetMixin

魔术视图类,控制自动生成路由,可以通过组合继承,以前的写法可以继续使用,但是如果要自动生成路由必须得继承ViewSetMixin及其子类;或者选择继承ViewSet、GenericViewSet

代码语言:javascript
复制
class ViewSetMixin:
    """
    This is the magic.

    Overrides `.as_view()` so that it takes an `actions` keyword that performs
    the binding of HTTP methods to actions on the Resource.

    For example, to create a concrete view binding the 'GET' and 'POST' methods
    to the 'list' and 'create' actions...

    view = MyViewSet.as_view({'get': 'list', 'post': 'create'})
    """
这就是魔法。  
 
重写' .as_view() ',以便它接受一个' actions '关键字执行  
将HTTP方法绑定到资源上的动作。  
 
例如,创建绑定'GET'和'POST'方法的具体视图  
到“列表”和“创建”动作…  
 
= MyViewSet视图。 As_view ({'get': 'list', 'post': 'create'})  

总结

补充

视图集中定义附加action动作

在视图集中,除了上述默认的方法动作外,还可以添加自定义动作。

举例:

代码语言:javascript
复制
from rest_framework.viewsets import ModelViewSet,ReadOnlyModelViewSet
class StudentModelViewSet(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

    def login(self,request):
        """学生登录功能"""
        return Response({"message":"登录成功"})

url的定义

代码语言:javascript
复制
urlpatterns = [
    path("students8/", views.StudentModelViewSet.as_view({"get": "list", "post": "create"})),
    re_path("students8/(?P<pk>\d+)/",
            views.StudentModelViewSet.as_view({"get": "retrieve", "put": "update", "delete": "destroy"})),

    path("stu/login/",views.StudentModelViewSet.as_view({"get":"login"}))

]

action属性

在视图集中,我们可以通过action对象属性来获取当前请求视图集时的action动作是哪个。

例如:

代码语言:javascript
复制
from rest_framework.viewsets import ModelViewSet
from students.models import Student
from .serializers import StudentModelSerializer
from rest_framework.response import Response
class StudentModelViewSet(ModelViewSet):
    queryset = Student.objects.all()
    serializer_class = StudentModelSerializer

    def get_new_5(self,request):
        """获取最近添加的5个学生信息"""
        # 操作数据库
        print(self.action) # 获取本次请求的视图方法名
        
        
通过路由访问到当前方法中.可以看到本次的action就是请求的方法名

累死🐵,有错误请指正~感谢

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-04-01,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • DRF 视图组件
  • 视图组件大纲
    • 两个视图基本类
      • 五个扩展类
        • 九个子类视图
          • 视图集
            • 常用视图集父类
            • 魔法类
          • 一览表
          • DRF中视图的“七十二变”
            • 第一层:基于APIview的五个接口
              • 第一层五个接口demo
            • 第二层:基于GenericAPIView的五个接口
              • 常用类属性:
              • 第二层五个接口demo
            • 第三层:基于GenericAPIView+五个视图扩展类写
              • 第三层五个接口demo
              • GenericAPIView速写五个接口demo
            • 第四层:GenericAPIView+九个视图子类写五个接口
              • 第四层快速写五个接口demo
            • 第五层:基于ViewSet写五个接口
              • 第五层基于ModelViewSet视图集写五个接口demo
              • ReadOnlyModelViewSet视图集
              • 两个视图集总结:
              • 其他视图集
            • 总结
              • 补充
                • 视图集中定义附加action动作
                • action属性
            相关产品与服务
            文件存储
            文件存储(Cloud File Storage,CFS)为您提供安全可靠、可扩展的共享文件存储服务。文件存储可与腾讯云服务器、容器服务、批量计算等服务搭配使用,为多个计算节点提供容量和性能可弹性扩展的高性能共享存储。腾讯云文件存储的管理界面简单、易使用,可实现对现有应用的无缝集成;按实际用量付费,为您节约成本,简化 IT 运维工作。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档