REST_FRAMEWORK重要组件--->View
7.视图(View)
- 过去写FBV/CBV很可能都是直接用的View类
- 现在写类增添了很多功能,会去使用APIView,且APIView是继承View的
- 复杂用:GenericAPIView
- 在settings中注册rest_framework方便调试内容、
from rest_framework.pagination import CursorPagination
class MyCursorPagination(CursorPagination):
max_page_size = 5
cursor_query_param = 'cursor'
page_size_query_param = 'page_size'
page_size = 2
ordering = 'username'
from rest_framework import serializers
class PageSerianlizer(serializers.ModelSerializer):
class Meta:
model=models.Userinfo
fields='__all__'
from rest_framework.generics import GenericAPIView
Class View(GenericAPIView):
queryset=models.Userinfo.objects.all()
Serializer_class=PageSerianlizer
pagination_class=MyCursorPagination
def get(self,request,*args,**kwargs):
users=self.get_queryset()
page_users=self.paginate_queryset(users)
ser=self.get_serializer(instance=page_users,many=True)
return Response(ser.data) --->这里利用的是response.Response类
- GenericViewset 继承(ViewsetMixin,GenericAPIView)
from rest_framework.viewsets import GenericViewset
Class View1(GenericViewset):
def get(self,request,*args,**kwargs):
return Response("ok")
url----->re_path(r'^test/viewset/$',views.view1.as_view()), 报错 for example‘as_view({'get':'list'})’
因为处理的机制是不同的,因为GenericViewset是多继承的,进去会先去ViewsetMixin类中找as_view()方法,在内部做
一个对应的关系。当发出get请求的时候,会去as_view里面找get请求,然后去类中找相对应的函数。
方法:def get()换成 def list() 或者在url中as_view()函数中变成as_view({'get':'get'}).做一个手写的对应关系
Post同样也可以写成as_view({'post':'post'}),对应关系后的函数名必须和View视图里面的一样的,不然出错。
因为GenericViewset是继承GenericAPIView的所以将、3、路由改一下,其他的不用变。
- Mixins
from rest_framekwork import mixins
Class View1(mixins.ListModelMixin,mixins.CreateModelMixin,GenericViewset):
queryset=models.Userinfo.all()
Serializer_class=PageSerianlizer
pagination_class=MyCursorPagination
url----->as_view({'get':'list','post':'create'}) 运行
因为view1是继承mixins.ListModelMixin,mixins.CreateModelMixin,在
mixins.ListModelMixin,mixins.CreateModelMixin中分别已经完成了对
list()和create()方法的编写,则只需要定义相对应的字段值就可以了。
mixins中还有RetrieveModelMixin/UpdateModelMixin/DestoryModelMixin类
如果只完成增删改查功能 -----> ModelViewset
如果只完成增删功能 —> mixins.ListModelMixin,mixins.CreateModelMixin,GenericViewset
复杂逻辑功能 —>GenericViewset / APIView
- ModelViewset
from rest_framework.viewsets import ModelViewset
Class view1(Modelviewset):
queryset=models.Userinfo.objects.all()
Serializer_class=PageSerianlizer
pagination_class=MyCursorPagination
url—>re_path(r’^test/viewset/(?p\d+’)/$,) 加上了参数pk表示可以指定单条数据
因为加上了pk参数,所以get请求从list(列表全部)变成了retrieve(单条数据)
Views.View1.as_view({'get':'retrieve','delete':'destory',
'put':'update'(全部),'patch':‘partial_update’(部分)})
一个url应该写2个路由,分get请求变成’list’、‘retrieve’.
可以按照以前方法去判断url有无关键参数 (pk=id)
def get(self,request,*args,**kwargs):
ret=kwargs.get('pk')
if ret: (有就是获取单条数据,没有就是list全部)
8.路由(Router)
我们除了可以自己手动指明请求方式与动作action之间的对应关系外,还可以使用Routers来帮助我们快速实现路由信息。
rest_framework提供了两个router:SimpleRouter、DefaultRouter
from rest_framework import routers
router = routers.SimpleRouter()
router.register(r'users', models.Userinfo.as_view(), base_name='user')
前缀 视图 路由名称的前缀
如上述代码会形成的路由如下:
^users/$ name:user-list
^users/{pk}/$ name: user-detail
可以通过这两种形式添加进路由里面:
urlpatterns = [
...
]
urlpatterns += router.urls
或
urlpatterns = [
...
url(r'^', include(router.urls))
]
视图集中包含附加action的
class BookInfoViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin, GenericViewSet):
queryset = UserInfo.objects.all()
serializer_class = UserInfoSerializer
@action(methods=['get'], detail=False)
def latest(self, request):
...
@action(methods=['put'], detail=True)
def read(self, request, pk):
...
此视图集会形成的路由:
^users/latest/$ name: user-latest
^users/{pk}/read/$ name: user-read
1) SimpleRouter
2)DefaultRouter
DefaultRouter与SimpleRouter的区别是,DefaultRouter会多附带一个默认的API根视图,返回一个包含所有列表视图的超链接响应数据。
from rest_framework import routers
router=routers.DefaultRouter()
router.register(r'***',View.view1) #通过routers类自动生成4个url,完成增删改查功能
url(r'^(?p<version>[v1][v2]+)/',include(router.urls)),
Router会根据视图里面的增删改查方法来决定产生几个路由
比如继承了ModelViewset会自动生成4个url如果继承mixins.ListModelMixin,mixins.CreateModelMixin,GenericViewset就只会产生2个url。
9.渲染器(Render)
from rest_framework.renders import JsonRenderer,BrowsableAPIRenderer
from rest_framework.response import Response
Class TestView(APIView):
def get(self,request,*args,**kwargs):
.......
return Response () 利用rest_framework中的response.Response返回。
其实可以在TestView中写入
renderer_classes=[JsonRenderer,BrowsableAPIRenderer]
意义为json类型返回和浏览器模式显示
也可以在全局settings中写入 "DEFAULT_RENDERER_CLASSES":['类路径',]
再URL上写上?format=json即用json类型显示数据。
用浏览器打开默认用BrowsableAPIRenderer显示。