Django Rest Framework源码剖析(八)-----视图与路由

发布时间:2020-01-11 发布网站:大佬教程
大佬教程收集整理的这篇文章主要介绍了Django Rest Framework源码剖析(八)-----视图与路由大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

<table style="height: 30px; background-color: #afeeee; width: 1266px; ; width: 1266px;" border="0"><tr>
<td><span style="font-size: 16px;">一、简介</td>
</tr></table>

django rest framework 给我们带来了很多组件,除了认证、权限、序列化...其中一个重要组件就是视图,一般视图是和路由配合使用,这种方式给我们提供了更灵活的使用方法,对于使用者而言不同的视图具有不同的功能,这样我们可以根据需求定制自己视图。以下是官网传送门:http://www.django-rest-framework.org/api-guide/views/

在之前的文章中,由于参杂了权限、认证等(如果不了解请看博客的以前的文章),但在本章中基本可以不使用,所进使用以下简单模型进行说明:

settings中注册django rest framework

INSTALLED_APPS =

models.py

django.db <span style="color: #008000;">#<span style="color: #008000;"> Create your models here.

<span style="color: #0000ff;">class<span style="color: #000000;"> UserInfo(models.Model):
username = models.CharField(max_length=32,unique=<span style="color: #000000;">True)
password = models.CharField(max_length=64)

urls.py

django.conf.urls django.contrib app01 =
二、各类视图使用1.APIView

该视图是最基本的视图,之前的章节中已经介绍如何使用,参考:

2.GenericAPIView

该视图为我们封装一些静态字段,用于调用其他组件,示例(解释请看注解):

django.shortcuts <span style="color: #008000;">#<span style="color: #008000;"> Create your views here.

<span style="color: #0000ff;">from rest_framework.response <span style="color: #0000ff;">import<span style="color: #000000;"> Response
<span style="color: #0000ff;">from rest_framework.generics <span style="color: #0000ff;">import<span style="color: #000000;"> GenericAPIView
<span style="color: #0000ff;">from rest_framework <span style="color: #0000ff;">import<span style="color: #000000;"> serializers
<span style="color: #0000ff;">from rest_framework <span style="color: #0000ff;">import<span style="color: #000000;"> pagination
<span style="color: #0000ff;">from app01 <span style="color: #0000ff;">import<span style="color: #000000;"> models

<span style="color: #0000ff;">class Userserializer(serializers.ModelSerializer): <span style="color: #008000;">#<span style="color: #008000;">序列化类定义,前面章节已经介绍
<span style="color: #0000ff;">class<span style="color: #000000;"> Meta:
model =<span style="color: #000000;"> models.UserInfo
fields = <span style="color: #800000;">'<span style="color: #800000;">all<span style="color: #800000;">' <span style="color: #008000;">#<span style="color: #008000;">序列化字段

<span style="color: #0000ff;">class Mypagination(pagination.PageNumberPagination): <span style="color: #008000;">#<span style="color: #008000;"> 分页类定义,前面章节也已经介绍
<span style="color: #800000;">"""<span style="color: #800000;">自定义分页<span style="color: #800000;">"""<span style="color: #000000;">
page_size=2 <span style="color: #008000;">#<span style="color: #008000;">默认每页显示个数配置
page_query_param = <span style="color: #800000;">'<span style="color: #800000;">p<span style="color: #800000;">' <span style="color: #008000;">#<span style="color: #008000;"> 页面传参的key,默认是page
page_size_query_param=<span style="color: #800000;">'<span style="color: #800000;">size<span style="color: #800000;">' <span style="color: #008000;">#<span style="color: #008000;"> 指定每页显示个数参数
max_page_size=4 <span style="color: #008000;">#<span style="color: #008000;"> 每页最多显示个数配置,使用以上配置,可以支持每页可显示2~4条数据

<span style="color: #0000ff;">class UerView(GenericAPIView): <span style="color: #008000;">#<span style="color: #008000;">视图
queryset = models.UserInfo.objects.all() <span style="color: #008000;">#<span style="color: #008000;">数据的queryset
serializer_class = Userserializer <span style="color: #008000;">#<span style="color: #008000;"> 序列化类使用
permission_classes = [] <span style="color: #008000;">#<span style="color: #008000;"> 权限认证,这里不做认证,前面章节也有介绍权限
pagination_class = Mypagination <span style="color: #008000;">#<span style="color: #008000;">分页类,前面章节也已经介绍
<span style="color: #0000ff;">def get(self,*args,**<span style="color: #000000;">kwargs):
roles=self.get_queryset() <span style="color: #008000;">#<span style="color: #008000;"> 获取queryset,实际取queryset,也就是models.UserInfo.objects.all()
page_res=self.paginate_queryset(queryset=roles) <span style="color: #008000;">#<span style="color: #008000;">分页结果
res=self.get_serializer(instance=page_res,many=True) <span style="color: #008000;">#<span style="color: #008000;">序列化
<span style="color: #0000ff;">return Response(res.data) <span style="color: #008000;">#<span style="color: #008000;">返回结果

访问http://127.0.0.1:8000/api/v1/users,查看结果如下:

Django Rest Framework源码剖析(八)-----视图与路由

3.GenericViewSet

该视图类需要和路由配合使用,修改后的urls.py

django.conf.urls django.contrib app01 = url(r,views.UserView.as_view({:,:})),

views.py

django.shortcuts <span style="color: #008000;">#<span style="color: #008000;"> Create your views here.

<span style="color: #0000ff;">from rest_framework.response <span style="color: #0000ff;">import<span style="color: #000000;"> Response
<span style="color: #0000ff;">from rest_framework.generics <span style="color: #0000ff;">import<span style="color: #000000;"> GenericAPIView
<span style="color: #0000ff;">from rest_framework <span style="color: #0000ff;">import<span style="color: #000000;"> serializers
<span style="color: #0000ff;">from rest_framework <span style="color: #0000ff;">import<span style="color: #000000;"> pagination
<span style="color: #0000ff;">from rest_framework.viewsets <span style="color: #0000ff;">import<span style="color: #000000;"> GenericViewSet
<span style="color: #0000ff;">from app01 <span style="color: #0000ff;">import<span style="color: #000000;"> models

<span style="color: #0000ff;">class Userserializer(serializers.ModelSerializer): <span style="color: #008000;">#<span style="color: #008000;">序列化类定义,前面章节已经介绍
<span style="color: #0000ff;">class<span style="color: #000000;"> Meta:
model =<span style="color: #000000;"> models.UserInfo
fields = <span style="color: #800000;">'<span style="color: #800000;">all<span style="color: #800000;">' <span style="color: #008000;">#<span style="color: #008000;">序列化字段

<span style="color: #0000ff;">class Mypagination(pagination.PageNumberPagination): <span style="color: #008000;">#<span style="color: #008000;"> 分页类定义,前面章节也已经介绍
<span style="color: #800000;">"""<span style="color: #800000;">自定义分页<span style="color: #800000;">"""<span style="color: #000000;">
page_size=2 <span style="color: #008000;">#<span style="color: #008000;">默认每页显示个数配置
page_query_param = <span style="color: #800000;">'<span style="color: #800000;">p<span style="color: #800000;">' <span style="color: #008000;">#<span style="color: #008000;"> 页面传参的key,默认是page
page_size_query_param=<span style="color: #800000;">'<span style="color: #800000;">size<span style="color: #800000;">' <span style="color: #008000;">#<span style="color: #008000;"> 指定每页显示个数参数
max_page_size=4 <span style="color: #008000;">#<span style="color: #008000;"> 每页最多显示个数配置,使用以上配置,可以支持每页可显示2~4条数据

<span style="color: #0000ff;">class UserView(GenericViewSet): <span style="color: #008000;">#<span style="color: #008000;">视图
queryset = models.UserInfo.objects.all() <span style="color: #008000;">#<span style="color: #008000;">数据的queryset
serializer_class = Userserializer <span style="color: #008000;">#<span style="color: #008000;"> 序列化类使用
permission_classes = [] <span style="color: #008000;">#<span style="color: #008000;"> 权限认证,这里不做认证,前面章节也有介绍权限
pagination_class = Mypagination <span style="color: #008000;">#<span style="color: #008000;">分页类,前面章节也已经介绍
<span style="color: #0000ff;">def show(self,**kwargs): <span style="color: #008000;">#<span style="color: #008000;">与url中映射的方法名称相同
roles=self.get_queryset() <span style="color: #008000;">#<span style="color: #008000;"> 获取queryset,实际取queryset,也就是models.UserInfo.objects.all()
page_res=self.paginate_queryset(queryset=roles) <span style="color: #008000;">#<span style="color: #008000;">分页结果
res=self.get_serializer(instance=page_res,many=True) <span style="color: #008000;">#<span style="color: #008000;">序列化
<span style="color: #0000ff;">return Response(res.data) <span style="color: #008000;">#<span style="color: #008000;">返回结果

<span style="color: #0000ff;"&gt;def</span> create(self,**<span style="color: #000000;"&gt;kwargs):
    </span><span style="color: #0000ff;"&gt;pass</span></pre>

访问http://127.0.0.1:8000/api/v2/users,结果和上面结果一样如图:

Django Rest Framework源码剖析(八)-----视图与路由

4.ModelViewSet

modelViewSet继承了mixins.CreateModelMixin、mixins.RetrieveModelMixin、mixins.UpdateModelMixin、mixins.DestroyModelMixin、mixins.ListModelMixin、GenericViewSet所以它有很父类的所有功能,而这些父类分别提供创建、获取、更新、删除等方法,所以我们不需要写增删该查,视图已经帮我实现了,示例:

此时路由urls.py

The urlpatterns list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views

  1. Add an import: from my_app import views
  2. Add a URL to urlpatterns: url(r'^$',views.home,name='home')
    Class-based views
  3. Add an import: from other_app.views import Home
  4. Add a URL to urlpatterns: url(r'^$',Home.as_view(),name='home')
    Including another URLconf
  5. Import the include() function: from django.conf.urls import url,include
  6. Add a URL to urlpatterns: url(r'^blog/',include('blog.urls'))
    <span style="color: #800000;">"""
    <span style="color: #0000ff;">from django.conf.urls <span style="color: #0000ff;">import<span style="color: #000000;"> url
    <span style="color: #0000ff;">from django.contrib <span style="color: #0000ff;">import<span style="color: #000000;"> admin
    <span style="color: #0000ff;">from app01 <span style="color: #0000ff;">import<span style="color: #000000;"> views
    urlpatterns =<span style="color: #000000;"> [
    url(r<span style="color: #800000;">'<span style="color: #800000;">^admin/<span style="color: #800000;">'<span style="color: #000000;">,url(r<span style="color: #800000;">'<span style="color: #800000;">^api/v1/users$<span style="color: #800000;">',views.UserView.as_view({<span style="color: #800000;">'<span style="color: #800000;">get<span style="color: #800000;">':<span style="color: #800000;">'<span style="color: #800000;">list<span style="color: #800000;">',<span style="color: #800000;">'<span style="color: #800000;">post<span style="color: #800000;">':<span style="color: #800000;">'<span style="color: #800000;">create<span style="color: #800000;">'<span style="color: #000000;">})),<span style="color: #008000;">#<span style="color: #008000;">路由,retrieve、delete、create、update、partial_update,在UserView的父类全部实现,其中pk参数必须携带,想当于key,类可操作
    url(r<span style="color: #800000;">'<span style="color: #800000;">^api/v1/users/(?P\d+)$<span style="color: #800000;">',views.UserView.as_view({<span style="color: #800000;">'<span style="color: #800000;">get<span style="color: #800000;">':<span style="color: #800000;">'<span style="color: #800000;">retrieve<span style="color: #800000;">',<span style="color: #800000;">'<span style="color: #800000;">delete<span style="color: #800000;">':<span style="color: #800000;">'<span style="color: #800000;">destroy<span style="color: #800000;">',<span style="color: #800000;">'<span style="color: #800000;">post<span style="color: #800000;">':<span style="color: #800000;">'<span style="color: #800000;">create<span style="color: #800000;">',<span style="color: #800000;">'<span style="color: #800000;">put<span style="color: #800000;">':<span style="color: #800000;">'<span style="color: #800000;">update<span style="color: #800000;">',<span style="color: #800000;">'<span style="color: #800000;">patch<span style="color: #800000;">':<span style="color: #800000;">'<span style="color: #800000;">partial_update<span style="color: #800000;">'<span style="color: #000000;">})),]

视图views.py

django.shortcuts

<span style="color: #008000;">#<span style="color: #008000;"> Create your views here.

<span style="color: #0000ff;">from rest_framework.response <span style="color: #0000ff;">import<span style="color: #000000;"> Response
<span style="color: #0000ff;">from rest_framework.generics <span style="color: #0000ff;">import<span style="color: #000000;"> GenericAPIView
<span style="color: #0000ff;">from rest_framework <span style="color: #0000ff;">import<span style="color: #000000;"> serializers
<span style="color: #0000ff;">from rest_framework <span style="color: #0000ff;">import<span style="color: #000000;"> pagination
<span style="color: #0000ff;">from rest_framework.viewsets <span style="color: #0000ff;">import<span style="color: #000000;"> ModelViewSet
<span style="color: #0000ff;">from app01 <span style="color: #0000ff;">import<span style="color: #000000;"> models

<span style="color: #0000ff;">class Userserializer(serializers.ModelSerializer): <span style="color: #008000;">#<span style="color: #008000;">序列化类定义,前面章节已经介绍
<span style="color: #0000ff;">class<span style="color: #000000;"> Meta:
model =<span style="color: #000000;"> models.UserInfo
fields = <span style="color: #800000;">'<span style="color: #800000;">all<span style="color: #800000;">' <span style="color: #008000;">#<span style="color: #008000;">序列化字段

<span style="color: #0000ff;">class Mypagination(pagination.PageNumberPagination): <span style="color: #008000;">#<span style="color: #008000;"> 分页类定义,前面章节也已经介绍
<span style="color: #800000;">"""<span style="color: #800000;">自定义分页<span style="color: #800000;">"""<span style="color: #000000;">
page_size=2 <span style="color: #008000;">#<span style="color: #008000;">默认每页显示个数配置
page_query_param = <span style="color: #800000;">'<span style="color: #800000;">p<span style="color: #800000;">' <span style="color: #008000;">#<span style="color: #008000;"> 页面传参的key,默认是page
page_size_query_param=<span style="color: #800000;">'<span style="color: #800000;">size<span style="color: #800000;">' <span style="color: #008000;">#<span style="color: #008000;"> 指定每页显示个数参数
max_page_size=4 <span style="color: #008000;">#<span style="color: #008000;"> 每页最多显示个数配置,使用以上配置,可以支持每页可显示2~4条数据

<span style="color: #0000ff;">class UserView(ModelViewSet): <span style="color: #008000;">#<span style="color: #008000;">视图
queryset = models.UserInfo.objects.all() <span style="color: #008000;">#<span style="color: #008000;">数据的queryset
serializer_class = Userserializer <span style="color: #008000;">#<span style="color: #008000;"> 序列化类使用
permission_classes = [] <span style="color: #008000;">#<span style="color: #008000;"> 权限认证,这里不做认证,前面章节也有介绍权限
pagination_class = Mypagination <span style="color: #008000;">#<span style="color: #008000;">分页类,前面章节也已经介绍

访问http://127.0.0.1:8000/api/v1/users/1,查看多增删改。

Django Rest Framework源码剖析(八)-----视图与路由

<table style="height: 30px; background-color: #afeeee; width: 1266px; ; width: 1266px;" border="0">

<tr>
<td><span style="font-size: 16px;">三、路由</td>
</tr></table>

前面的示例中已经用到类路由的功能,在这里介绍下router使用方法,一般情况,我们写路由时候对于增删该查可能写多个路由,其实我们可以借助DRF的router自动帮我们生成路由,示例:

The urlpatterns list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/1.11/topics/http/urls/
Examples:
Function views

  1. Add an import: from my_app import views
  2. Add a URL to urlpatterns: url(r'^$',include('blog.urls'))
    <span style="color: #800000;">"""
    <span style="color: #0000ff;">from django.conf.urls <span style="color: #0000ff;">import<span style="color: #000000;"> url,include
    <span style="color: #0000ff;">from django.contrib <span style="color: #0000ff;">import<span style="color: #000000;"> admin
    <span style="color: #0000ff;">from app01 <span style="color: #0000ff;">import<span style="color: #000000;"> views
    <span style="color: #0000ff;">from rest_framework <span style="color: #0000ff;">import<span style="color: #000000;"> routers
    router=routers.DefaultRouter() <span style="color: #008000;">#<span style="color: #008000;">是列化router类
    router.register(r<span style="color: #800000;">'<span style="color: #800000;">userinfo$<span style="color: #800000;">',views.UserView) <span style="color: #008000;">#<span style="color: #008000;">注册一个url,后续会生成我们想要的个url

<span style="color: #008000;">#<span style="color: #008000;">#生成的url
<span style="color: #000000;">

urlpatterns =<span style="color: #000000;"> [
url(r<span style="color: #800000;">'<span style="color: #800000;">^admin/<span style="color: #800000;">'<span style="color: #000000;">,<span style="color: #008000;">#<span style="color: #008000;">路由,retrieve、delete、create、update、partial_update,在UserView的父类全部实现
url(r<span style="color: #800000;">'<span style="color: #800000;">^api/v1/users/(?P\d+)$<span style="color: #800000;">',url(r<span style="color: #800000;">'<span style="color: #800000;">^api/v1<span style="color: #800000;">',include(router.urls)),<span style="color: #008000;">#<span style="color: #008000;">将生成的url加入到路由中
]

此时我们找一个不存在的页面查看路由:

Django Rest Framework源码剖析(八)-----视图与路由

需要知道的知识点:

  • 子类拥有父类的所有功能

由于视图类较多,所以我们对源码的剖析就不一一分析了,这里以一个常用的GenericAPIView为例子分析下源码。首先从继承角度来说,GenericAPIView继承了APIView,而APIView又继承了View,而APIView是对django原生的View类的dispatch方法进行了重写(在认证的篇章已经说明),所以GenericAPIView具有APIView和View的所有功能,下面是GenericAPIView源码,分析部分请看注释:

queryset = serializer_class =</span></span><span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; If you want to use object lookups other than pk,set 'lookup_field'.</span> <span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; For more complex lookup requirements override `get_object()`.</span> lookup_field = <span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;pk</span><span style="color: #800000;"&gt;' <span style="color: #ff6600;"&gt; # 浏览条数据使用的pk</span></span><span style="color: #000000;"&gt; lookup_url_kwarg </span>=<span style="color: #000000;"&gt; None </span><span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; The filter backend classes to use for queryset filtering</span> filter_backends =<span style="color: #000000;"&gt; api_settings.DEFAULT_FILTER_BACKENDS <span style="color: #ff6600;"&gt; # 过滤配置 </span></span><span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; The style to use for queryset pagination.</span> pagination_class =<span style="color: #000000;"&gt; api_settings.DEFAULT_PAGINATION_CLASS <span style="color: #ff6600;"&gt; #分页配置 </span></span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; get_queryset(self): <span style="color: #ff6600;"&gt; # 获取queryset方法 </span></span><span style="color: #800000;"&gt;"""</span><span style="color: #800000;"&gt; Get the list of items for this view. This must be an iterable,and may be a queryset. Defaults to using `self.queryset`. This method should always be used rather than accessing `self.queryset` directly,as `self.queryset` gets evaluated only once,and those results are cached for all subsequent requests. You may want to override this if you need to provide different querysets depending on the incoming request. (Eg. return a list of items that is specific to the user) </span><span style="color: #800000;"&gt;"""</span> <span style="color: #0000ff;"&gt;assert</span> self.queryset <span style="color: #0000ff;"&gt;is</span> <span style="color: #0000ff;"&gt;not</span><span style="color: #000000;"&gt; None,( </span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;'%s' should either include a `queryset` attribute,</span><span style="color: #800000;"&gt;"</span> <span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;or override the `get_queryset()` method.</span><span style="color: #800000;"&gt;"</span> % self.<span style="color: #800080;"&gt;__class__</span>.<span style="color: #800080;"&gt;__name__</span><span style="color: #000000;"&gt; ) queryset </span>=<span style="color: #000000;"&gt; self.queryset <span style="color: #ff6600;"&gt;# 将配置querset 转化为类属性 </span></span><span style="color: #0000ff;"&gt;if</span><span style="color: #000000;"&gt; isinstance(queryset,QuerySet): <span style="color: #ff6600;"&gt; # 判断配置queryset是不是QuerySet类型 </span></span><span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; Ensure queryset is re-evaluated on each request.</span> queryset =<span style="color: #000000;"&gt; queryset.all() <span style="color: #ff6600;"&gt; # 返回所有该Queryset类型的数据 </span></span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; queryset </span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; get_object(self): <span style="color: #ff6600;"&gt; # 获取单个的对象,需要在url中配置pk,其中pk的参数一般是ID </span></span><span style="color: #800000;"&gt;"""</span><span style="color: #800000;"&gt; Returns the object the view is displaying. You may want to override this if you need to provide non-standard queryset lookups. Eg if objects are referenced using multiple keyword arguments in the url conf. </span><span style="color: #800000;"&gt;"""</span><span style="color: #000000;"&gt; queryset </span>=<span style="color: #000000;"&gt; self.filter_queryset(self.get_queryset()) </span><span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; Perform the lookup filtering.</span> lookup_url_kwarg = self.lookup_url_kwarg <span style="color: #0000ff;"&gt;or</span><span style="color: #000000;"&gt; self.lookup_field </span><span style="color: #0000ff;"&gt;assert</span> lookup_url_kwarg <span style="color: #0000ff;"&gt;in</span><span style="color: #000000;"&gt; self.kwargs,( </span><span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;Expected view %s to be called with a URL keyword argument </span><span style="color: #800000;"&gt;'</span> <span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;named "%s". Fix your URL conf,or set the `.lookup_field` </span><span style="color: #800000;"&gt;'</span> <span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;attribute on the view correctly.</span><span style="color: #800000;"&gt;'</span> %<span style="color: #000000;"&gt; (self.</span><span style="color: #800080;"&gt;__class__</span>.<span style="color: #800080;"&gt;__name__</span><span style="color: #000000;"&gt;,lookup_url_kwarg) ) filter_kwargs </span>=<span style="color: #000000;"&gt; {self.lookup_field: self.kwargs[lookup_url_kwarg]} obj </span>= get_object_or_404(queryset,**<span style="color: #000000;"&gt;filter_kwargs) </span><span style="color: #008000;"&gt;#</span><span style="color: #008000;"&gt; May raise a permission denied</span>

<span style="color: #000000;"> self.check_object_permissions(self.request,obj) <span style="color: #ff6600;"># 检查请求是否有该对象权限,也就是权限篇章定义权限时候不可少的方法,如不过没定义会,执行权限验证的时候就会抛出异常。

    </span></span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; obj

</span><span style="color: #0000ff;"&gt;def</span> get_serializer(self,**<span style="color: #000000;"&gt;kwargs):   #<span style="color: #ff6600;"&gt; 获取序列化类
    </span></span><span style="color: #800000;"&gt;"""</span><span style="color: #800000;"&gt;
    Return the serializer instance that should be used for validating and
    deserializing input,and for serializing output.
    </span><span style="color: #800000;"&gt;"""</span><span style="color: #000000;"&gt;
    serializer_class </span>=<span style="color: #000000;"&gt; self.get_serializer_class()  <span style="color: #ff6600;"&gt;# 执行get_serializer_class用于获取序列化类</span>
    kwargs[</span><span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;context</span><span style="color: #800000;"&gt;'</span>] =<span style="color: #000000;"&gt; self.get_serializer_context() 
    </span><span style="color: #0000ff;"&gt;return</span> serializer_class(*args,**<span style="color: #000000;"&gt;kwargs) <span style="color: #ff6600;"&gt; # 序列化数据,返回序列化以后的结果

</span></span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; get_serializer_class(self):  <span style="color: #ff6600;"&gt;# 获取序列化类 ,也就是serialzier_class配置
    </span></span><span style="color: #800000;"&gt;"""</span><span style="color: #800000;"&gt;
    Return the class to use for the serializer.
    Defaults to using `self.serializer_class`.

    You may want to override this if you need to provide different
    serializations depending on the incoming request.

    (Eg. admins get full serialization,others get basic serialization)
    </span><span style="color: #800000;"&gt;"""</span>
    <span style="color: #0000ff;"&gt;assert</span> self.serializer_class <span style="color: #0000ff;"&gt;is</span> <span style="color: #0000ff;"&gt;not</span><span style="color: #000000;"&gt; None,(    <span style="color: #ff6600;"&gt; # 判断序列化类是否存在
        </span></span><span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;'%s' should either include a `serializer_class` attribute,</span><span style="color: #800000;"&gt;"</span>
        <span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;or override the `get_serializer_class()` method.</span><span style="color: #800000;"&gt;"</span>
        % self.<span style="color: #800080;"&gt;__class__</span>.<span style="color: #800080;"&gt;__name__    </span><span style="color: #000000;"&gt;
    )

    </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; self.serializer_class 

</span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; get_serializer_context(self):
    </span><span style="color: #800000;"&gt;"""</span><span style="color: #800000;"&gt;
    Extra context provided to the serializer class.
    </span><span style="color: #800000;"&gt;"""</span>
    <span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; {
        </span><span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;request</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;: self.request,</span><span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;format</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;: self.format_kwarg,</span><span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;view</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;: self
    }

</span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; filter_queryset(self,queryset): <span style="color: #ff6600;"&gt;# 过滤,参数为queryset
    </span></span><span style="color: #800000;"&gt;"""</span><span style="color: #800000;"&gt;
    Given a queryset,filter it with whichever filter backend is in use.

    You are unlikely to want to override this method,although you may need
    to call it either from a list view,or from a custom `get_object`
    method if you want to apply the configured filtering backend to the
    default queryset.
    </span><span style="color: #800000;"&gt;"""</span>
    <span style="color: #0000ff;"&gt;for</span> backend <span style="color: #0000ff;"&gt;in</span><span style="color: #000000;"&gt; list(self.filter_backends): 
        queryset </span>=<span style="color: #000000;"&gt; backend().filter_queryset(self.request,queryset,self)
    </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; queryset

@property
</span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; paginator(self):  <span style="color: #ff6600;"&gt;#属性方法,用于获取分页对象
    </span></span><span style="color: #800000;"&gt;"""</span><span style="color: #800000;"&gt;
    The paginator instance associated with the view,or `None`.
    </span><span style="color: #800000;"&gt;"""</span>
    <span style="color: #0000ff;"&gt;if</span> <span style="color: #0000ff;"&gt;not</span> hasattr(self,<span style="color: #800000;"&gt;'</span><span style="color: #800000;"&gt;_paginator</span><span style="color: #800000;"&gt;'</span><span style="color: #000000;"&gt;):   <span style="color: #ff6600;"&gt;# 判断分页对象是否存在
        </span></span><span style="color: #0000ff;"&gt;if</span> self.pagination_class <span style="color: #0000ff;"&gt;is</span><span style="color: #000000;"&gt; None:    
            self._paginator </span>=<span style="color: #000000;"&gt; None     <span style="color: #ff6600;"&gt;#不存在返回none
        </span></span><span style="color: #0000ff;"&gt;else</span><span style="color: #000000;"&gt;:
            self._paginator </span>=<span style="color: #000000;"&gt; self.pagination_class()<span style="color: #ff6600;"&gt;  # 存在返回分页对象
    </span></span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; self._paginator

</span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; paginate_queryset(self,queryset):
    </span><span style="color: #800000;"&gt;"""</span><span style="color: #800000;"&gt;
    Return a single page of results,or `None` if pagination is disabled.
    </span><span style="color: #800000;"&gt;"""</span>
    <span style="color: #0000ff;"&gt;if</span> self.paginator <span style="color: #0000ff;"&gt;is</span><span style="color: #000000;"&gt; None:
        </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; None
    </span><span style="color: #0000ff;"&gt;return</span> self.paginator.paginate_queryset(queryset,self.request,view=<span style="color: #000000;"&gt;self) <span style="color: #ff6600;"&gt; # 调用分页对象的分页方法,返回分页数据

</span></span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; get_paginated_response(self,data):           <span style="color: #ff6600;"&gt;# 使用分页对象响应请求,页面显示时候比较美观提供一些操作方法,除此之外无其他作用
    </span></span><span style="color: #800000;"&gt;"""</span><span style="color: #800000;"&gt;
    Return a paginated style `Response` object for the given output data.
    </span><span style="color: #800000;"&gt;"""</span>
    <span style="color: #0000ff;"&gt;assert</span> self.paginator <span style="color: #0000ff;"&gt;is</span> <span style="color: #0000ff;"&gt;not</span><span style="color: #000000;"&gt; None
    </span><span style="color: #0000ff;"&gt;return</span> self.paginator.get_paginated_response(data)         </pre>
使用建议:

1.对于简单的数据模型来说,建议使用modelViewSet,因为它已经帮我们写好了增删该查接口。

2.对于复杂的数据模型,比如涉及多个表操作或有事务要求时,此时更建议使用APIView或者GenericAPIView,这样可以根据需求我们自己写增删该查接口。

大佬总结

以上是大佬教程为你收集整理的Django Rest Framework源码剖析(八)-----视图与路由全部内容,希望文章能够帮你解决Django Rest Framework源码剖析(八)-----视图与路由所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ群:277859234,请注明来意。