视图

使用混合(mixins)

有多张表,多个类,这些类的代码除了从数据库的数据和相应的序列化类不一样,其他都一样,可以做第一步封装。原先做的封装成函数,然后调用函数,但是这里是利用类的继承,这是一种可以借鉴的方式。把逻辑部分封装成父类,代码不同的地方做配置即可。为了满足做一下配置就完成功能,这里使用了​​generics.GenericAPIView​

class UserView(mixins.ListModelMixin,
mixins.CreateModelMixin,
generics.GenericAPIView):
# 这两个是经常变动部分,做成配置,逻辑部分做了封装
queryset = User.objects.all()
serializer_class = UserSerializer

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

def post(self, request, *args, **kwargs):
return self.create(request, *args, **kwargs)

class SingleUserView(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
generics.GenericAPIView):

queryset = User.objects.all()
serializer_class = UserSerializer
# lookup_field = 'pk'
def get(self, request, *args, **kwargs):
return self.retrieve(request, *args, **kwargs)

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

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

mixed-in

上述做了第一步封装,可以把get,post等请求方式也封装

from rest_framework import generics

class UserView(generics.ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer

class SingleUserView(generics.RetrieveUpdateDestroyAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer

viewsets.ModelViewSet

上面两种封装都是基于视图的封装,但是路由是两条

urlpatterns = [
url(r'^user/$', UserView.as_view()),
url(r'^user/(?P<pk>\d+)$', SingleUserView.as_view())]

既然都是对User表的操作,为啥不考虑合成一个类来处理,而不是分成UserView和SingleUserView两个类来处理。考虑合成一条路由的方式

    url(r'^user/$', UserView.as_view({'get':'list', 'post':'create'})),
url(r'^user/(?P<pk>\d+)$', UserView.as_view({'get':'retrieve', 'put':'update','delete':'destroy'})),

from rest_framework.viewsets import ModelViewSet

class UserView(ModelViewSet):
queryset = User.objects.all()
serializer_class = UserSerializer

源码流程

因为as_view()此时可以接收参数,所以肯定需要重写as_view方法

django restframework视图、路由系统和渲染器_json

django restframework视图、路由系统和渲染器_json_02

django restframework视图、路由系统和渲染器_封装_03

django restframework视图、路由系统和渲染器_django_04

请求进来匹配url的时候才会进行字典对应关系的绑定,而不是django程序启动就做了绑定(因为这样get方法还是只会对应一个方法)

渲染器

根据 用户请求URL 或 用户可接受的类型,筛选出合适的 渲染组件。

用户请求URL:

其中​​http://127.0.0.1:8000/api/v1/user.json​​需要新增url

渲染器其实就是为了显示用的,用处不是很大。

from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer

class UserView(ModelViewSet):
renderer_classes = [JSONRenderer, BrowsableAPIRenderer]
queryset = User.objects.all()
serializer_class = UserSerializer

全局配置

REST_FRAMEWORK = {
"DEFAULT_VERSIONING_CLASS":"rest_framework.versioning.URLPathVersioning",
"DEFAULT_VERSION":'v1',
"ALLOWED_VERSIONS":['v1','v2'],
"VERSION_PARAM":'version',
"DEFAULT_PARSER_CLASSES":['rest_framework.parsers.JSONParser','rest_framework.parsers.FormParser'],
"PAGE_SIZE":2,

"DEFAULT_RENDERER_CLASSES":[
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
]
}

路由系统

自动生成路由

from django.conf.urls import url, include
from .views import *
from rest_framework import routers

router = routers.DefaultRouter()
router.register('user', UserView)

urlpatterns = [
# url(r'^user/$', UserView.as_view()),
url(r'', include(router.urls))]

这样自动生成路由的方式需要view继承ModelViewSet

django restframework视图、路由系统和渲染器_封装_05