Django REST framwork 提供的视图的主要作用:
控制序列化器的执行(检验、保存、转换数据) 控制数据库模型的操作 REST framework 提供了众多的通用视图基类与扩展类,以简化视图的编写。
两个视图基类 APIView 1 rest_framework.views.APIView
APIView
是REST framework提供的所有视图的基类,继承自Django的View
父类。
APIView
与View
的不同之处在于:
传入到视图方法中的是REST framework的Request
对象,而不是Django的HttpRequeset
对象; 视图方法可以返回REST framework的Response
对象,视图会为响应数据设置(render)符合前端要求的格式; 任何APIException
异常都会被捕获到,并且处理成合适的响应信息; 在进行dispatch()分发前,会对请求进行身份认证、权限检查、流量控制。 支持定义的属性
authentication_classes 列表或元祖,身份认证类permissoin_classes 列表或元祖,权限检查类throttle_classes 列表或元祖,流量控制类在APIView
中仍以常规的类视图定义方法来实现get() 、post() 或者其他请求方式的方法。
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 class BookView (APIView ): def get (self, request ): book_list = Book.objects.all () serializer = BookSerializers(instance=book_list, many=True ) ''' serializer 做了些什么 temp = [] for obj in book_list: d = {} d[title] = obj.title d[price] = obj.price d[pub_date] = obj.pub_date temp.append(d) ''' return Response(serializer.data) ................得写5 个接口 增删改查查
GenericAPIView[通用视图类] 用于构建通用的视图,主要作用就是把视图中的独特的代码抽取出来,让视图方法中的代码更加通用,方便把通用代码进行简写。
1 rest_framework.generics.GenericAPIView
继承自APIVIew
,主要增加了操作序列化器和数据库查询的方法,作用是为下面Mixin扩展类的执行提供方法支持。通常在使用时,可搭配一个或多个Mixin扩展类。
提供的关于序列化器使用的属性与方法
get_serializer_class(self) get_serializer_class
是 GenericAPIView
类中的一个方法,用于确定在序列化过程中应该使用哪个序列化器类。
这个方法通常返回的是视图类中的 serializer_class
属性所指定的序列化器类。如果视图类没有定义 serializer_class
,或者需要根据特定条件动态选择序列化器类,那么可以在子类中重写 get_serializer_class
方法以提供自定义逻辑。
get_serializer(self, *args, **kwargs) get_serializer
方法则用于根据 get_serializer_class
返回的序列化器类来创建序列化器的实例。这个方法通常接受一些参数,如 data
、instance
、files
等,用于初始化序列化器。
在视图的各个方法(如 get
, post
, put
等)中,你通常会调用 self.get_serializer()
来获取一个适当的序列化器实例,并用于处理请求或响应数据。
get_queryset(self) get_queryset
方法是用于获取与视图相关联的模型对象的查询集
默认情况下,它返回视图类中定义的queryset
属性。如果你需要根据某些条件来过滤查询集,你可以重写这个方法
返回视图使用的查询集,主要用来提供给Mixin扩展类使用,是列表视图与详情视图获取数据的基础,默认返回queryset
属性,可以重写,例如:
1 2 3 def get_queryset (self ): user = self.request.user return user.accounts.all ()
get_queryset
通常在需要列出多个对象时使用,例如在API的列表视图中。get_object(self) get_object
方法用于获取查询集中的单个对象实例。它通常在详情视图(Detail View)或基于类的视图中使用
在试图中可以调用该方法获取详情信息的模型类对象,默认情况下,它使用查询集和URL中提供的查找字段来检索对象。
所以:
get_object
方法确实依赖于URL配置中的查找字段(lookup field)来检索单个对象。默认情况下,这个查找字段是模型的主键(pk
),并且URL配置应该使用有名分组(named group)来捕获这个字段的值。
1 2 3 4 5 6 7 8 urlpatterns = [ path("book/" , views.BookView.as_view()), re_path("book/(?P<pk>\d+)/" , views.BookDetailView.as_view()), path("book/<int:pk>" , views.BookDetailView.as_view()) ]
在这个配置中,<int:pk>
是一个有名分组,它捕获一个整数作为主键,并将其作为pk
关键字参数传递给BookDetailView
若详情访问的模型类对象不存在,会返回404。
该方法会默认使用APIView提供的check_object_permissions方法检查当前对象是否有权限被访问。
也可以重写该方法
1 2 3 4 5 6 7 8 class BookDetailView (RetrieveAPIView ): queryset = Book.objects.all () serializer_class = BookSerializers lookup_field = 'slug' urlpatterns = [ path('book/<slug:slug>/' , BookDetailView.as_view()), ]
get_object
通常在需要获取和操作单个对象时使用,例如在API的详情视图中。
其他可以设置的属性
pagination_class 指明分页控制类filter_backends 指明过滤控制后端GenericAPIView示例 大家可以对比下GenericAPIView示例与APIView示例
1 2 3 4 5 6 7 from django.db import modelsclass Book (models.Model): title = models.CharField(max_length=32 ,verbose_name="书籍名称" ) price = models.IntegerField(verbose_name="价格" , null=True ) pub_date = models.DateField(verbose_name="出版日期" )
1 2 3 4 5 6 7 8 9 10 11 from rest_framework import serializersfrom .models import Bookclass BookSerializers (serializers.ModelSerializer): date = serializers.DateField(source="pub_date" ) class Meta : model = Book exclude = ['pub_date' ]
1 2 3 4 5 6 7 8 9 10 11 from django.urls import path,re_pathfrom sers import viewsurlpatterns = [ path("book/" , views.BookView.as_view()), re_path("book/(?P<pk>\d+)/" , views.BookDetailView.as_view()), path("book/<int:pk>" , views.BookDetailView.as_view()) ]
最大的区别,以后在写其他视图类,只需要复制-黏贴修改class 类名
、queryset 模型类
、serializer_class 序列化类
,其他都不需要修改
因为get_object
访问的模型类对象不存在,自己会返回404,就不需要辅助判断查询的数据存在否
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 from rest_framework.generics import GenericAPIViewfrom rest_framework.response import Responsefrom .models import Bookfrom .serializers import BookSerializersclass BookView (GenericAPIView ): queryset = Book.objects.all () serializer_class = BookSerializers def get (self, request ): serializer = self.get_serializer(instance=self.get_queryset(),many=True ) return Response(serializer.data) def post (self, request ): print ("data" , request.data) serializer = self.get_serializer(data=request.data) if serializer.is_valid(): serializer.save() return Response(serializer.data) else : return Response(serializer.errors) class BookDetailView (GenericAPIView ): queryset = Book.objects.all () serializer_class = BookSerializers def get (self, request, pk ): serializer = self.get_serializer(instance=self.get_object(), many=False ) return Response(serializer.data) def put (self, request, pk ): serializer = self.get_serializer(instance=self.get_object(), data=request.data, many=False ) if serializer.is_valid(): serializer.save() return Response(serializer.data) else : return Response(serializer.errors) def delete (self, request, pk ): self.get_object().delete() return Response()
五个视图扩展类 作用:
提供了几种后端视图(对数据资源进行曾删改查)处理流程的实现,如果需要编写的视图属于这五种,则视图可以通过继承相应的扩展类来复用代码,减少自己编写的代码量。
这五个扩展类需要搭配GenericAPIView父类,因为五个扩展类的实现需要调用GenericAPIView提供的序列化器与数据库查询的方法。
ListModelMixin 列表视图扩展类,提供list(request, *args, **kwargs)
方法快速实现列表视图,返回200状态码。
该Mixin的list方法会对数据进行过滤和分页。
源代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class ListModelMixin (object ): """ List a queryset. """ def list (self, request, *args, **kwargs ): queryset = self.filter_queryset(self.get_queryset()) page = self.paginate_queryset(queryset) if page is not None : serializer = self.get_serializer(page, many=True ) return self.get_paginated_response(serializer.data) serializer = self.get_serializer(queryset, many=True ) return Response(serializer.data)
举例:
1 2 3 4 5 6 class BookView (GenericAPIView, ListModelMixin): queryset = Book.objects.all () serializer_class = BookSerializers def get (self, request ): return self.list (request)
CreateModelMixin 创建视图扩展类,提供create(request, *args, **kwargs)
方法快速实现创建资源的视图,成功返回201状态码。
如果序列化器对前端发送的数据验证失败,返回400错误。
源代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class CreateModelMixin (object ): """ Create a model instance. """ def create (self, request, *args, **kwargs ): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True ) self.perform_create(serializer) headers = self.get_success_headers(serializer.data) return Response(serializer.data, status=status.HTTP_201_CREATED, headers=headers) def perform_create (self, serializer ): serializer.save() def get_success_headers (self, data ): try : return {'Location' : str (data[api_settings.URL_FIELD_NAME])} except (TypeError, KeyError): return {}
举例:
1 2 3 4 5 class BookView (GenericAPIView, CreateModelMixin): queryset = Book.objects.all () serializer_class = BookSerializers def post (self, request ): return self.create(request)
RetrieveModelMixin 详情视图扩展类,提供retrieve(request, *args, **kwargs)
方法,可以快速实现返回一个存在的数据对象。
如果存在,返回200, 否则返回404。
源代码:
1 2 3 4 5 6 7 8 9 10 class RetrieveModelMixin (object ): """ Retrieve a model instance. """ def retrieve (self, request, *args, **kwargs ): instance = self.get_object() serializer = self.get_serializer(instance) return Response(serializer.data)
举例:
1 2 3 4 5 6 class BookDetailView (RetrieveModelMixin, GenericAPIView): queryset = Book.objects.all () serializer_class = BookSerializer def get (self, request, pk ): return self.retrieve(request)
UpdateModelMixin 更新视图扩展类,提供update(request, *args, **kwargs)
方法,可以快速实现更新一个存在的数据对象。
同时也提供partial_update(request, *args, **kwargs)
方法,可以实现局部更新。
成功返回200,序列化器校验数据失败时,返回400错误。
源代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 class UpdateModelMixin (object ): """ Update a model instance. """ def update (self, request, *args, **kwargs ): partial = kwargs.pop('partial' , False ) instance = self.get_object() serializer = self.get_serializer(instance, data=request.data, partial=partial) serializer.is_valid(raise_exception=True ) self.perform_update(serializer) if getattr (instance, '_prefetched_objects_cache' , None ): instance._prefetched_objects_cache = {} return Response(serializer.data) def perform_update (self, serializer ): serializer.save() def partial_update (self, request, *args, **kwargs ): kwargs['partial' ] = True return self.update(request, *args, **kwargs)
举例:
1 2 3 4 5 class BookDetailView (GenericAPIView, UpdateModelMixin): queryset = Book.objects.all () serializer_class = BookSerializers def put (self, request, pk ): return self.update(request, pk)
DestroyModelMixin 删除视图扩展类,提供destroy(request, *args, **kwargs)
方法,可以快速实现删除一个存在的数据对象。
成功返回204,不存在返回404。
源代码:
1 2 3 4 5 6 7 8 9 10 11 class DestroyModelMixin (object ): """ Destroy a model instance. """ def destroy (self, request, *args, **kwargs ): instance = self.get_object() self.perform_destroy(instance) return Response(status=status.HTTP_204_NO_CONTENT) def perform_destroy (self, instance ): instance.delete()
举例:
1 2 3 4 5 class BookDetailView (GenericAPIView, DestroyModelMixin): queryset = Book.objects.all () serializer_class = BookSerializers def delete (self, request, pk ): return self.destroy(request, pk)
基于Mixin的视图示例 以GenericAPIView示例为例 修改views.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 from rest_framework.generics import GenericAPIViewfrom rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixinfrom .models import Bookfrom .serializers import BookSerializersclass BookView (ListModelMixin, CreateModelMixin, GenericAPIView): queryset = Book.objects.all () serializer_class = BookSerializers def get (self, request ): return self.list (request) def post (self, request ): return self.create(request) class BookDetailView (RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin, GenericAPIView): queryset = Book.objects.all () serializer_class = BookSerializers 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)
GenericAPIView的子类视图 CreateAPIView 提供 post 方法
继承自: GenericAPIView、CreateModelMixin
ListAPIView 提供 get 方法
继承自:GenericAPIView、ListModelMixin
ListCreateAPIView 提供 get 和 post 方法
继承自:GenericAPIView、ListModelMixin、CreateModelMixin
RetrieveAPIView 提供 get 方法
继承自:GenericAPIView、RetrieveModelMixin
UpdateAPIView 提供 put/patch 方法
继承自:GenericAPIView、UpdateModelMixin
DestroyAPIView 提供 delete 方法
继承自:GenericAPIView、DestroyModelMixin
RetrieveUpdateAPIView 提供 get 和 put/patch 方法
继承自:GenericAPIView、RetrieveModelMixin、UpdateModelMixin
RetrieveDestroyAPIView 提供 get 和 delete 方法
继承自:GenericAPIView、RetrieveModelMixin、DestroyModelMixin
RetrieveUpdateDestroyAPIView 提供 get、put/patch 和 delete 方法
继承自:GenericAPIView、RetrieveModelMixin、UpdateModelMixin、DestroyModelMixin
这些子类视图都是 Django REST framework 提供的,它们基于 GenericAPIView
和不同的 mixin 类来提供特定的 HTTP 方法。每个视图都专注于处理一种或多种特定的操作,如创建、获取、更新或删除对象。通过组合不同的 mixin 类,可以轻松地构建出满足特定需求的视图。
请注意,这些视图类通常还需要你指定 queryset
和 serializer_class
属性,以便它们知道如何与数据库中的模型进行交互,以及如何序列化和反序列化数据。这些属性通常在视图类的类定义中设置。
这些视图类大大简化了 RESTful API 的开发过程,因为它们已经实现了许多常见的操作,开发者只需要关注于具体的业务逻辑和数据模型。
基于GenericAPIView的子类视图示例 以GenericAPIView示例为例 修改views.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIViewfrom .models import Bookfrom .serializers import BookSerializersclass BookView (ListCreateAPIView ): queryset = Book.objects.all () serializer_class = BookSerializers class BookDetailView (RetrieveUpdateDestroyAPIView ): queryset = Book.objects.all () serializer_class = BookSerializers
视图集 使用视图集ViewSet,可以将一系列逻辑相关的动作放到一个类中:
list() 提供一组数据 retrieve() 提供单个数据 create() 创建数据 update() 保存数据 destory() 删除数据 ViewSet视图集类不再实现get()、post()等方法,而是实现动作 action 如 list() 、create() 等。
视图集只在使用as_view()方法的时候,才会将action 动作与具体请求方式对应上。如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 class BookViewSet (viewsets.ViewSet): def list (self, request ): books = Book.objects.all () serializer = BookSerializer(books, many=True ) return Response(serializer.data) def retrieve (self, request, pk=None ): try : books = Book.objects.get(id =pk) except Book.DoesNotExist: return Response(status=status.HTTP_404_NOT_FOUND) serializer = BookSerializer(books) return Response(serializer.data)
在设置路由时,我们可以如下操作
1 2 3 4 urlpatterns = [ url(r'^books/$' , BookViewSet.as_view({'get' :'list' }), url(r'^books/(?P<pk>\d+)/$' , BookViewSet.as_view({'get' : 'retrieve' }) ]
ViewSet 继承自APIView
与ViewSetMixin
,作用也与APIView基本类似,提供了身份认证、权限校验、流量管理等。
ViewSet主要通过继承ViewSetMixin来实现在调用as_view()时传入字典(如{‘get’:‘list’})的映射处理工作。
在ViewSet中,没有提供任何动作action方法,需要我们自己实现action方法。
使用视图集ViewSet,可以将一系列视图相关的代码逻辑和相关的http请求动作封装到一个类中:
list() 提供一组数据 retrieve() 提供单个数据 create() 创建数据 update() 保存数据 destory() 删除数据 ViewSet视图集类不再限制视图方法名只允许get()、post()等这种情况了,而是实现允许开发者根据自己的需要定义自定义方法名,例如 list() 、create() 等,然后经过路由中使用http和这些视图方法名进行绑定调用。
为了方便演示视图集的使用,我们新建一个子应用,
1 python manage.py startapp vset
视图集只在使用as_view()方法的时候,才会将action 动作与具体请求方式对应上。如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 from django.urls import path, re_pathfrom vset.views import BookViewurlpatterns = [ path("books/" , BookView.as_view({ "get" : "get_all_book" , "post" : "add_book" })), re_path("^books/(?P<pk>\d+)$" , BookView.as_view({ "get" : "get_one_book" , "put" : "edit_book" , "delete" : "delete" , })), ]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 from rest_framework import serializersfrom rest_framework import statusfrom rest_framework.response import Responsefrom rest_framework.viewsets import ViewSetfrom sers.models import Bookclass BookSerializer (serializers.ModelSerializer): class Meta : model = Book fields = "__all__" class BookView (ViewSet ): def get_all_book (self, request ): books = Book.objects.all () bs = BookSerializer(instance=books, many=True ) return Response(bs.data) def add_book (self, request ): bs = BookSerializer(data=request.data) if bs.is_valid(): bs.save() return Response(bs.data) else : return Response(bs.errors) def get_one_book (self, request, pk ): book = Book.objects.get(pk=pk) bs = BookSerializer(instance=book) return Response(bs.data) def edit_book (self, request, pk ): instance = Book.objects.get(pk=pk) bs = BookSerializer(instance=instance, data=request.data) if bs.is_valid(): bs.save() return Response(bs.data) else : return Response(bs.errors) def delete (self, request, pk ): Book.objects.get(pk=pk).delete() return Response(status=status.HTTP_204_NO_CONTENT)
GenericViewSet 继承自GenericAPIView和ViewSetMixin,作用让视图集的视图代码变得更加通用,抽离独特代码作为视图类的属性。
使用ViewSet通常并不方便,因为list、retrieve、create、update、destory等方法都需要自己编写,而这些方法与前面讲过的Mixin扩展类提供的方法同名,所以我们可以通过继承Mixin扩展类来复用这些方法而无需自己编写。但是Mixin扩展类依赖与GenericAPIView
,所以还需要继承GenericAPIView
。
GenericViewSet 就帮助我们完成了这样的继承工作,继承自GenericAPIView
与ViewSetMixin
,在实现了调用as_view()时传入字典(如{'get':'list'}
)的映射处理工作的同时,还提供了GenericAPIView
提供的基础方法,可以直接搭配Mixin扩展类使用。
举例:
models.py urls.py serializers.py views.py1 2 3 4 5 6 7 from django.db import modelsclass Book (models.Model): title = models.CharField(max_length=32 ,verbose_name="书籍名称" ) price = models.IntegerField(verbose_name="价格" , null=True ) pub_date = models.DateField(verbose_name="出版日期" )
1 2 3 4 5 6 7 8 9 10 from django.urls import path, re_pathfrom sers import viewsurlpatterns = [ path("book/" , views.BookView.as_view({"get" : "list" , "post" : "create" })), path("book/<int:pk>" , views.BookView.as_view({"get" : "retrieve" , "delete" : "destroy" , "put" : "update" })) ]
1 2 3 4 5 6 7 8 9 10 11 from rest_framework import serializersfrom .models import Bookclass BookSerializers (serializers.ModelSerializer): date = serializers.DateField(source="pub_date" ) class Meta : model = Book exclude = ['pub_date' ]
1 2 3 4 5 6 7 8 9 10 11 12 from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixinfrom rest_framework.viewsets import GenericViewSetfrom rest_framework.views import Responsefrom .models import Bookfrom .serializers import BookSerializersclass BookView (GenericViewSet, ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin): queryset = Book.objects.all () serializer_class = BookSerializers
ModelViewSet 继承自GenericViewSet
,同时包括了ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin。
1 2 3 4 5 6 7 8 9 10 11 12 from rest_framework.viewsets import ModelViewSetfrom .models import Bookfrom .serializers import BookSerializersclass BookView (ModelViewSet ): queryset = Book.objects.all () serializer_class = BookSerializers
ReadOnlyModelViewSet 继承自GenericViewSet
,同时包括了ListModelMixin、RetrieveModelMixin。
1 2 3 4 5 from rest_framework.viewsets import ModelViewSetclass BookView (ModelViewSet ): queryset = Book.objects serializer_class = BookSerializer
视图集中定义附加action动作 在视图集中,除了上述默认的方法动作外,还可以添加自定义动作。
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 from rest_framework import mixinsfrom rest_framework.viewsets import GenericViewSetfrom rest_framework.decorators import actionclass BookViewSet (mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet): queryset = Book.objects.all () serializer_class = BookSerializer def latest (self, request ): """ 返回最新的图书信息 """ book = Book.objects.latest('id' ) serializer = self.get_serializer(book) return Response(serializer.data) def read (self, request, pk ): """ 修改图书的阅读量数据 """ book = self.get_object() book.bread = request.data.get('read' ) book.save() serializer = self.get_serializer(book) return Response(serializer.data)
url的定义
1 2 3 4 5 6 urlpatterns = [ url(r'^books/$' , views.BookViewSet.as_view({'get' : 'list' })), url(r'^books/latest/$' , views.BookViewSet.as_view({'get' : 'latest' })), url(r'^books/(?P<pk>\d+)/$' , views.BookViewSet.as_view({'get' : 'retrieve' })), url(r'^books/(?P<pk>\d+)/read/$' , views.BookViewSet.as_view({'put' : 'read' })), ]
action属性 在视图集中,我们可以通过action对象属性来获取当前请求视图集时的action动作是哪个。
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 from rest_framework.viewsets import ModelViewSet,ReadOnlyModelViewSetfrom booktest.models import Bookfrom .serializers import BookModelSerializerfrom rest_framework.response import Responseclass BookModelViewSet (ModelViewSet ): queryset = Book.objects.all () serializer_class = BookModelSerializer def get_top_5 (self,request ): """获取评论值最多的5条数据""" print (self.action) 通过路由访问到当前方法中.可以看到本次的action就是请求的方法名
路由Routers 对于视图集ViewSet,我们除了可以自己手动指明请求方式与动作action之间的对应关系外,还可以使用Routers来帮助我们快速实现路由信息。
REST framework提供了两个router
SimpleRouter DefaultRouter 使用方法 1) 创建router对象,并注册视图集,例如
1 2 3 from rest_framework import routersrouter = routers.DefaultRouter() router.register('book' , BookView, base_name='book' )
register(prefix, viewset, base_name)
prefix 该视图集的路由前缀 viewset 视图集 base_name 路由别名的前缀 如上述代码会形成的路由如下:
1 2 ^book/$ name: book-list ^book/{pk}/$ name: book-detail
2)添加路由数据
可以有两种方式:
1 2 3 4 5 urlpatterns = [ ... ] urlpatterns += router.urls
或
1 2 3 4 5 urlpatterns = [ ... path('^' , include(router.urls)) ]
路由代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 from django.urls import path, re_pathfrom . import viewsurlpatterns = [ ... ] """使用drf提供路由类router给视图集生成路由列表""" from rest_framework.routers import DefaultRouterrouter = DefaultRouter() router.register("book" ,views.BookView) print ( router.urls )urlpatterns += router.urls
上面的代码就成功生成了路由地址[增/删/改/查一条/查多条的功能],但是不会自动我们在视图集自定义方法的路由。
所以我们如果也要给自定义方法生成路由,则需要进行action动作的声明。
视图集中附加action的声明 在视图集中,如果想要让Router自动帮助我们为自定义的动作生成路由信息,需要使用rest_framework.decorators.action
装饰器。
以action装饰器装饰的方法名会作为action动作名,与list、retrieve等同。
action装饰器可以接收两个参数:
举例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 from rest_framework.viewsets import ModelViewSetfrom rest_framework.decorators import actionclass BookView (ModelViewSet ): queryset = Book.objects serializer_class = BookSerializer """ action装饰器的作用:告诉路由类给视图集的自定义方法生成路由信息 methods, 列表,允许哪些http请求能访问当前视图方法 detail,布尔,生成路由时是否拼接pk参数 detail为True,表示路径名格式应该为 book/{pk}/login/ url_path,字符串,生成路由时末尾路由路径,如果没有声明,则自动以当前方法名作为路由尾缀 """ @action(methods=['get' ], detail=True ,url_path="login" ) def login (self, request,pk ): """登录""" return Response({"msg" :request.method}) @action(methods=['get' ], detail=False ) def get_new_5 (self, request ): """获取最新添加的5本书""" ...
由路由器自动为此视图集自定义action方法形成的路由会是如下内容:
1 2 ^book/get_new_5/$ name: book-get_new_5 ^book/{pk}/login/$ name: book-login
路由router形成URL的方式 1) SimpleRouter(prefix=“路由前缀”,viewset=视图集类,basename=“路由别名”)
2)DefaultRouter
DefaultRouter与SimpleRouter的区别是,DefaultRouter会多附带一个默认的API根视图,返回一个包含所有列表视图的超链接响应数据。