加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 大数据 > 正文

DRF 视图和路由

发布时间:2020-12-15 17:17:44 所属栏目:大数据 来源:网络整理
导读:Django Rest Feamework 视图和路由 DRF的视图 APIView 我们django中写CBV的时候继承的是View,rest_framework继承的是APIView,那么他们两个有什么不同呢 urlpatterns = d+)$ 我们可以看到,不管是View还是APIView最开始调用的都是as_view()方法~~那我们走

Django Rest Feamework 视图和路由

DRF的视图

APIView

我们django中写CBV的时候继承的是View,rest_framework继承的是APIView,那么他们两个有什么不同呢

urlpatterns =d+)$

我们可以看到,不管是View还是APIView最开始调用的都是as_view()方法~~那我们走进源码看看~~

我们能看到,APIView继承了View,并且执行了View中的as_view()方法,最后把view返回了,用csrf_exempt()方法包裹后去掉了csrf的认证。

那我们看看View中的as_view()方法做了什么~

我们看到了~在View中的as_view方法返回了view函数,而view函数执行了self.dispatch()方法~~但是这里的dispatch方法应该是我们APIView中的~~

我们去initialize_request中看下把什么赋值给了request,并且赋值给了self.request,也就是我们在视图中用的request.xxx到底是什么~~

我们看到,这个方法返回的是Request这个类的实例对象~~我们注意我们看下这个Request类中的第一个参数request,是我们走我们django的时候的原来的request~

我们看到了,这个Request类把原来的request赋值给了self._request,也就是说以后_request是我们老的request,新的request是我们这个Request类~~

那我们继承APIView之后请求来的数据都在哪呢~~

我们用了rest_framework框架以后,我们的request是重新封装的Request类~

request.query_params 存放的是我们get请求的参数

request.data 存放的是我们所有的数据,包括post请求的以及put,patch请求~~~

相比原来的django的request,我们现在的request更加精简,清晰了~~~

现在我们知道了APIView和View的一些区别~~当然还有~~后面我们还会说~~

我们写的视图可能对多个表进行增删改查,就导致我们的视图特别多重复的代码~~

那么我们尝试着来进行封装一下~~

第一次封装

</span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; get(self,request): query_set </span>=<span style="color: #000000;"&gt; Book.objects.all() book_ser </span>= BookSerializer(query_set,many=<span style="color: #000000;"&gt;True) </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; Response(book_ser.data) </span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; post(self,request): query_set </span>=<span style="color: #000000;"&gt; request.data book_ser </span>= BookSerializer(data=<span style="color: #000000;"&gt;query_set) </span><span style="color: #0000ff;"&gt;if</span><span style="color: #000000;"&gt; book_ser.is_valid(): book_ser.save() </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; Response(book_ser.validated_data) </span><span style="color: #0000ff;"&gt;else</span><span style="color: #000000;"&gt;: </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; Response(book_ser.errors)

<span style="color: #0000ff;">class<span style="color: #000000;"> BookEditView(APIView):

</span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; get(self,request,id):
    query_set </span>= Book.objects.filter(id=<span style="color: #000000;"&gt;id).first()
    book_ser </span>=<span style="color: #000000;"&gt; BookSerializer(query_set)
    </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; Response(book_ser.data)

</span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; patch(self,id):
    query_set </span>= Book.objects.filter(id=<span style="color: #000000;"&gt;id).first()
    book_ser </span>= BookSerializer(query_set,data=request.data,partial=<span style="color: #000000;"&gt;True)
    </span><span style="color: #0000ff;"&gt;if</span><span style="color: #000000;"&gt; book_ser.is_valid():
        book_ser.save()
        </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; Response(book_ser.validated_data)
    </span><span style="color: #0000ff;"&gt;else</span><span style="color: #000000;"&gt;:
        </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; Response(book_ser.errors)

</span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; delete(self,id):
    query_set </span>= Book.objects.filter(id=<span style="color: #000000;"&gt;id).first()
    </span><span style="color: #0000ff;"&gt;if</span><span style="color: #000000;"&gt; query_set:
        query_set.delete()
        </span><span style="color: #0000ff;"&gt;return</span> Response(<span style="color: #800000;"&gt;""</span><span style="color: #000000;"&gt;)
    </span><span style="color: #0000ff;"&gt;else</span><span style="color: #000000;"&gt;:
        </span><span style="color: #0000ff;"&gt;return</span> Response(<span style="color: #800000;"&gt;"</span><span style="color: #800000;"&gt;删除的书籍不存在</span><span style="color: #800000;"&gt;"</span>)</pre>
==</span><span style="color: #0000ff;"&gt;def</span><span style="color: #000000;"&gt; get_queryset(self): </span><span style="color: #0000ff;"&gt;return</span><span style="color: #000000;"&gt; self.queryset.all() </span><span style="color: #0000ff;"&gt;def</span> get_serializer(self,*args,**<span style="color: #000000;"&gt;kwargs): </span><span style="color: #0000ff;"&gt;return</span> self.serializer_class(*args,**<span style="color: #000000;"&gt;kwargs)

<span style="color: #0000ff;">class<span style="color: #000000;"> ListModelMixin(object):
<span style="color: #0000ff;">def list(self,**<span style="color: #000000;">kwargs):
queryset =<span style="color: #000000;"> self.get_queryset()
serializer = self.get_serializer(queryset,many=<span style="color: #000000;">True)
<span style="color: #0000ff;">return<span style="color: #000000;"> Response(serializer.data)

<span style="color: #0000ff;">class<span style="color: #000000;"> CreateModelMixin(object):
<span style="color: #0000ff;">def create(self,**<span style="color: #000000;">kwargs):
serializer = self.get_serializer(data=<span style="color: #000000;">request.data)
<span style="color: #0000ff;">if<span style="color: #000000;"> serializer.is_valid():
serializer.save()
<span style="color: #0000ff;">return<span style="color: #000000;"> Response(serializer.validated_data)
<span style="color: #0000ff;">else<span style="color: #000000;">:
<span style="color: #0000ff;">return<span style="color: #000000;"> Response(serializer.errors)

<span style="color: #0000ff;">class<span style="color: #000000;"> RetrieveModelMixin(object):
<span style="color: #0000ff;">def retrieve(self,id,**<span style="color: #000000;">kwargs):
book_obj = self.get_queryset().filter(pk=<span style="color: #000000;">id).first()
book_ser =<span style="color: #000000;"> self.get_serializer(book_obj)
<span style="color: #0000ff;">return<span style="color: #000000;"> Response(book_ser.data)

<span style="color: #0000ff;">class<span style="color: #000000;"> UpdateModelMixin(object):
<span style="color: #0000ff;">def update(self,**<span style="color: #000000;">kwargs):
book_obj = self.get_queryset().filter(pk=<span style="color: #000000;">id).first()
book_ser = self.get_serializer(book_obj,partial=<span style="color: #000000;">True)
<span style="color: #0000ff;">if<span style="color: #000000;"> book_ser.is_valid():
book_ser.save()
<span style="color: #0000ff;">return<span style="color: #000000;"> Response(book_ser.validated_data)
<span style="color: #0000ff;">else<span style="color: #000000;">:
<span style="color: #0000ff;">return<span style="color: #000000;"> Response(book_ser.errors)

<span style="color: #0000ff;">class<span style="color: #000000;"> DestroyModelMixin(object):
<span style="color: #0000ff;">def destroy(self,**<span style="color: #000000;">kwargs):
queryset =<span style="color: #000000;"> self.get_queryset()
<span style="color: #0000ff;">try<span style="color: #000000;">:
queryset.get(pk=<span style="color: #000000;">id).delete()
<span style="color: #0000ff;">return Response(<span style="color: #800000;">""<span style="color: #000000;">)
<span style="color: #0000ff;">except<span style="color: #000000;"> Exception as e:
<span style="color: #0000ff;">return Response(<span style="color: #800000;">"<span style="color: #800000;">信息有误<span style="color: #800000;">"<span style="color: #000000;">)
<span style="color: #008000;">#<span style="color: #008000;"> 我们把公共的部分抽出来 这样不管写多少表的增删改查都变的很简单<span style="color: #008000;">

<span style="color: #008000;"> 这样封装后我们的视图会变成这样

<span style="color: #0000ff;">class<span style="color: #000000;"> BookView(GenericAPIView,ListModelMixin,CreateModelMixin):
queryset =<span style="color: #000000;"> Book.objects.all()
serializer_class =<span style="color: #000000;"> BookSerializer

</span><span style="color: #0000ff;"&gt;def</span> get(self,**<span style="color: #000000;"&gt;kwargs):
    </span><span style="color: #0000ff;"&gt;return</span> self.list(request,**<span style="color: #000000;"&gt;kwargs)

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

<span style="color: #0000ff;">class<span style="color: #000000;"> BookEditView(GenericAPIView,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin):
queryset =<span style="color: #000000;"> Book.objects.all()
serializer_class =<span style="color: #000000;"> BookSerializer

</span><span style="color: #0000ff;"&gt;def</span> get(self,**<span style="color: #000000;"&gt;kwargs):
    </span><span style="color: #0000ff;"&gt;return</span> self.retrieve(request,**<span style="color: #000000;"&gt;kwargs)

</span><span style="color: #0000ff;"&gt;def</span> patch(self,**<span style="color: #000000;"&gt;kwargs):
    </span><span style="color: #0000ff;"&gt;return</span> self.update(request,**<span style="color: #000000;"&gt;kwargs)

</span><span style="color: #0000ff;"&gt;def</span> destroy(self,**<span style="color: #000000;"&gt;kwargs):
    </span><span style="color: #0000ff;"&gt;return</span> self.delete(request,**kwargs)</pre>

我们封装的GenericAPIView,包括封装每个方法的类,其实框架都帮我们封装好了

我们可以直接继承这些类~~来实现上面的视图~~可是还有没有更简单的方法呢~我们再次封装一下

第二次封装

<span style="color: #0000ff;">class<span style="color: #000000;"> ListCreateAPIView(GenericAPIView,CreateModelMixin):
<span style="color: #0000ff;">pass

<span style="color: #0000ff;">class<span style="color: #000000;"> RetrieveUpdateDestroyAPIView(GenericAPIView,DestroyModelMixin):
<span style="color: #0000ff;">pass

<span style="color: #0000ff;">class<span style="color: #000000;"> BookView(ListCreateAPIView):
queryset =<span style="color: #000000;"> Book.objects.all()
serializer_class =<span style="color: #000000;"> BookSerializer

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

<span style="color: #0000ff;">class<span style="color: #000000;"> BookEditView(RetrieveUpdateDestroyAPIView):
queryset =<span style="color: #000000;"> Book.objects.all()
serializer_class =<span style="color: #000000;"> BookSerializer

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

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

这次我们只是让继承变的简单了一点而已,好像并没有什么大的进步~~

我们可不可以把这两个视图合并成一个视图呢~~~框架给我们提供了一个路由传参的方法~~

我们看下ViewSetMixin

actions这个默认参数其实就是我们路由可以进行传参了~~~

下面这个循环~可以看出~我们要传的参数是一个字段~key应该是我们的请求方式,value应该对应我们处理的方法~

这样我们每个视图就不用在写函数了~因为已经和内部实现的函数相对应了~

第三次封装

urlpatterns = d+)$', url(r,BookView.as_view({: ,: d+)$,BookView.as_view({: ,: ,:
rest_framework.viewsets <span style="color: #008000;">#<span style="color: #008000;"> class BookView(ViewSetMixin,ListCreateAPIView,RetrieveUpdateDestroyAPIView):<span style="color: #008000;">

<span style="color: #008000;"> queryset = Book.objects.all()<span style="color: #008000;">

<span style="color: #008000;"> serializer_class = BookSerializer

<span style="color: #008000;">#<span style="color: #008000;"> 如果我们再定义一个类
<span style="color: #0000ff;">class<span style="color: #000000;"> ModelViewSet(ViewSetMixin,RetrieveUpdateDestroyAPIView):
<span style="color: #0000ff;">pass

<span style="color: #0000ff;">class<span style="color: #000000;"> BookView(ModelViewSet):
queryset =<span style="color: #000000;"> Book.objects.all()
serializer_class = BookSerializer

?我们现在的视图就只要写两行就可以了~~~

其实我们写的所有的视图~框架都帮我们封装好了~

注意一点~~用框架封装的视图~我们url上的那个关键字参数要用pk~~系统默认的~~

奉献一张图来看下我们的继承顺序~~~

DRF的路由

1,自定义路由

django.conf.urls web.views urlpatterns =<span style="color: #000000;"> [
url(r
<span style="color: #800000;">'
<span style="color: #800000;">^test/$
<span style="color: #800000;">'
<span style="color: #000000;">,s11_render.TestView.as_view()),url(r
<span style="color: #800000;">'<span style="color: #800000;">^test.(?P[a-z0-9]+)$<span style="color: #800000;">'<span style="color: #000000;">,url(r<span style="color: #800000;">'<span style="color: #800000;">^test/(?P[^/.]+)/$<span style="color: #800000;">'<span style="color: #000000;">,url(r<span style="color: #800000;">'<span style="color: #800000;">^test/(?P[^/.]+).(?P[a-z0-9]+)$<span style="color: #800000;">'<span style="color: #000000;">,s11_render.TestView.as_view())
]

rest_framework.views rest_framework.response .. <span style="color: #0000ff;">class<span style="color: #000000;"> TestView(APIView):
<span style="color: #0000ff;">def
get(self,**<span style="color: #000000;">kwargs):
<span style="color: #0000ff;">print
<span style="color: #000000;">(kwargs)
<span style="color: #0000ff;">print
<span style="color: #000000;">(self.renderer_classes)
<span style="color: #0000ff;">return Response(<span style="color: #800000;">'<span style="color: #800000;">...<span style="color: #800000;">')

2,半自动路由

django.conf.urls web.views urlpatterns =<span style="color: #000000;"> [
url(r
<span style="color: #800000;">'
<span style="color: #800000;">^test/$
<span style="color: #800000;">'
,s10_generic.UserViewSet.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;">})),url(r<span style="color: #800000;">'<span style="color: #800000;">^test/(?Pd+)/$<span style="color: #800000;">'<span style="color: #000000;">,s10_generic.UserViewSet.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;">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: #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: #000000;">})),]

rest_framework.viewsets rest_framework .. <span style="color: #0000ff;">class<span style="color: #000000;"> UserSerializer(serializers.ModelSerializer):
<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: #0000ff;">class<span style="color: #000000;"> UserViewSet(ModelViewSet):
queryset =<span style="color: #000000;"> models.UserInfo.objects.all()
serializer_class = UserSerializer

3,全自动路由

django.conf.urls rest_framework web.views router =<span style="color: #000000;"> routers.DefaultRouter()
router.register(r
<span style="color: #800000;">'
<span style="color: #800000;">users
<span style="color: #800000;">'
<span style="color: #000000;">,s10_generic.UserViewSet)

urlpatterns =<span style="color: #000000;"> [
url(r<span style="color: #800000;">'<span style="color: #800000;">^<span style="color: #800000;">'<span style="color: #000000;">,include(router.urls)),]

rest_framework.viewsets rest_framework .. <span style="color: #0000ff;">class<span style="color: #000000;"> UserSerializer(serializers.ModelSerializer):
<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: #0000ff;">class<span style="color: #000000;"> UserViewSet(ModelViewSet):
queryset =<span style="color: #000000;"> models.UserInfo.objects.all()
serializer_class = UserSerializer

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读