视图组件

[TOC]

一、基本视图

class PublishView(APIView):

    def get(self, request):
publish_list = Publish.objects.all()
bs = PublishSerializers(publish_list, many=True) return JsonResponse(bs.data,safe=False) def post(self, request):
# 添加一条数据
print(request.data) bs = PublishSerializers(data=request.data)
if bs.is_valid():
bs.save() # 生成记录
return JsonResponse(bs.data,safe=False)
else: return JsonResponse(bs.errors,safe=False) class PublishDetailView(APIView):
def get(self, request, pk):
publish_obj = Publish.objects.filter(pk=pk).first()
bs = PublishSerializers(publish_obj, many=False)
return JsonResponse(bs.data,safe=False) def put(self, request, pk):
publish_obj = Publish.objects.filter(pk=pk).first() bs = PublishSerializers(data=request.data, instance=publish_obj)
if bs.is_valid():
bs.save() # update
return JsonResponse(bs.data)
else:
return JsonResponse(bs.errors) def delete(self, request, pk):
Publish.objects.filter(pk=pk).delete() return JsonResponse("")

二、自定义的封装视图

class Create:
def create(self,request):
bs = serializers(data=request.data)
if bs.is_valid():
bs.save() # 生成记录
return JsonResponse(bs.data,safe=False)
else:
return JsonResponse(bs.errors,safe=False) class List:
def list(self,request):
queryset = self.queryset
bs = self.serializers(queryset, many=True)
return JsonResponse(bs.data,safe=False) # 将create和 list方法抽出来,封装起来
class PublishView(APIView,List,Create):
queryset=Publish.objects.all()
serializers=PublishSerializers
def get(self, request):
return self.list(request)
def post(self, request):
return self.create(request) class BookView(APIView,List,Create):
queryset=Book.objects.all()
serializers=BookSerializer
def get(self, request):
return self.list(request)
def post(self, request):
return self.create(request)

三、利用mixin类和generice类编写视图

1、使用

# ListModelMixin 查询所有;  CreateModelMixin:创建数据;  RetrieveModelMixin:查询一条;   UpdateModelMixin:更新数据;  DestroyModelMixin:删除数据
from rest_framework.mixins import ListModelMixin, CreateModelMixin, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin
from rest_framework.generics import GenericAPIView class PublishView(GenericAPIView,ListModelMixin,CreateModelMixin):
queryset = Publish.objects.all()
serializer_class = PublishSerializers
def get(self, request):
# self.list(request),ListModelMixin类中的函数属性
return self.list(request)
def post(self, request):
return self.create(request) class BookView(GenericAPIView,ListModelMixin,CreateModelMixin):
queryset = Book.objects.all()
serializer_class = BookSerializers
def get(self, request):
return self.list(request)
def post(self, request):
return self.create(request)

2、源码

(1)ListModelMixin类
class ListModelMixin(object):
def list(self, request, *args, **kwargs):
# 获取queryset对象,filter_queryset是利用过滤条件过滤
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)
(2)self.get_queryset()与self.get_serializer()
# self.get_queryset()
# 先自身找,然后类中找,再去父类GenericAPIView中找,找到
def get_queryset(self):
# queryset在GenericAPIView设默认值为None,因此要重新定义queryset,指定queryset对象
queryset = self.queryset
if isinstance(queryset, QuerySet):
# 查询所有数据
queryset = queryset.all()
return queryset
# self.get_serializer()
# 先自身找,然后类中找,再去父类GenericAPIView中找,找到
def get_serializer(self, *args, **kwargs):
# get_serializer_class()返回的是serializer_class,默认值为None,所以要重新定义返回的是serializer_class
serializer_class = self.get_serializer_class()
kwargs['context'] = self.get_serializer_context()
return serializer_class(*args, **kwargs)
(3)CreateModelMixin类下的create
class CreateModelMixin(object):
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()
(4)UpdateModelMixin类下的update
class UpdateModelMixin(object):

    def update(self, request, *args, **kwargs):
partial = kwargs.pop('partial', False)
# get_object 返回的是一个普通对象
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()
(5)DestroyModelMixin类下的destroy
class DestroyModelMixin(object):

    def destroy(self, request, *args, **kwargs):
# get_object 返回的是一个普通对象
instance = self.get_object()
self.perform_destroy(instance)
return Response(status=status.HTTP_204_NO_CONTENT) def perform_destroy(self, instance):
instance.delete()
(6)RetrieveModelMixin类下的retrieve
class RetrieveModelMixin(object):
#
def retrieve(self, request, *args, **kwargs):
# get_object 返回的是一个普通对象
instance = self.get_object()
serializer = self.get_serializer(instance)
return Response(serializer.data)

四、利用generics 下的ListCreateAPIView,RetrieveUpdateDestroyAPIView

1、使用

from rest_framework.generics import ListCreateAPIView, ListAPIView, RetrieveUpdateDestroyAPIView

# 继承了ListCreateAPIView类,而ListCreateAPIView又继承了多个类,并且定义了get和post方法,因此,只需要重定义queryset和serializer_class即可
class PublishView(ListCreateAPIView):
queryset = Publish.objects.all()
serializer_class = PublishSerializers class PublishDetailView(RetrieveUpdateDestroyAPIView):
queryset = Publish.objects.all()
serializer_class = PublishSerializers

2、源码

# 继承了多个类,类中的方法也是调用了GenericAPIView类中的list、create函数属性
class ListCreateAPIView(mixins.ListModelMixin,
mixins.CreateModelMixin,
GenericAPIView): 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 RetrieveUpdateDestroyAPIView(mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
GenericAPIView): 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 patch(self, request, *args, **kwargs):
return self.partial_update(request, *args, **kwargs) def delete(self, request, *args, **kwargs):
return self.destroy(request, *args, **kwargs)

五、使用ModelViewSet(不建议使用)

1、使用

# 路由层
url(r'^publish', views.PublishView.as_view({'get': 'list', 'post': 'create'})),
url(r'^publish/(?P<pk>\d+)', views.PublishView.as_view({'get': 'retrieve', 'put': 'update','delete':'destroy'})), # 视图层 from rest_framework.views import APIView
from rest_framework.viewsets import ModelViewSet
from rest_framework.renderers import JSONRenderer,BrowsableAPIRenderer
class PublishView(ModelViewSet):
queryset = Publish.objects.all()
serializer_class = PublishSerializers

2、源码

class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet):
pass class GenericViewSet(ViewSetMixin, generics.GenericAPIView):
pass # ViewSetMixin是一个魔法类,重写了as_view方法,所以继承该类的时候,一般放前面,否则会调用APIView的as_view方法
class ViewSetMixin(object):
"""
This is the magic.
view = MyViewSet.as_view({'get': 'list', 'post': 'create'})
""" @classonlymethod
def as_view(cls, actions=None, **initkwargs):
cls.name = None
cls.description = None
cls.suffix = None
cls.detail = None
cls.basename = None def view(request, *args, **kwargs):
self = cls(**initkwargs) # actions ---> {'get': 'list', 'post': 'create'}
self.action_map = actions for method, action in actions.items():
handler = getattr(self, action)
# 将list方法的地址赋给get,create方法的地址赋给post
# 将list绑定给GET,create绑定给POST
setattr(self, method, handler) if hasattr(self, 'get') and not hasattr(self, 'head'):
self.head = self.get self.request = request
self.args = args
self.kwargs = kwargs # And continue as usual
return self.dispatch(request, *args, **kwargs) # take name and docstring from class
update_wrapper(view, cls, updated=()) update_wrapper(view, cls.dispatch, assigned=()) view.cls = cls
view.initkwargs = initkwargs
view.actions = actions
return csrf_exempt(view)

六、强调:ViewSetMixin魔法类

  • ViewSetMixin类重写了as_view方法,因此为了调用它的as_view方法,在继承的时候,要写在APIView前面
class TestAll(ViewSetMixin,APIView):
pass
  • ViewSetMixin 类可以实现全部视图函数写在一个类中
# 路由层
[
url(r'^test1/$', views.TestAll.as_view({'get': 'test'})), # 将test视图函数赋给get
url(r'^test2/$', views.TestAll.as_view({'get': 'test2'})),
url(r'^test3/$', views.TestAll.as_view({'get': 'test3'}))
] # 视图层
class TestAll(ViewSetMixin,APIView):
def test(self,request):
return HttpResponse('test') def test2(self, request):
return HttpResponse('test2') def test3(self, request):
return HttpResponse('test3')

Django框架(二十四)—— Django rest_framework-视图组件的更多相关文章

  1. Django框架(十四)-- forms组件、局部钩子、全局钩子

    一.什么是forms组件 forms组件就是一个类,可以检测前端传来的数据,是否合法. 例如,前端传来的邮箱数据,判断邮件格式对不对,用户名中不能以什么开头,等等 二.forms组件的使用 1.使用语 ...

  2. Django框架之第四篇(视图层)--HttpRequest对象、HttpResponse对象、JsonResponse、CBV和FBV、文件上传

    视图层 一.视图函数 一个视图函数,简称视图,是一个简单的python函数,它接收web请求并且会返回web响应.响应可以是一张网页的html,一个重定向,或者是一张图片...任何东西都可以.无论是什 ...

  3. Django框架(十四)—— Django分页组件

    目录 Django分页组件 一.分页器 二.分页器的使用 三.案例 1.模板层 2.视图层 Django分页组件 一.分页器 数据量大的话,可以分页获取,查看 例如:图书管理中,如果有成千上万本书,要 ...

  4. React文档(二十四)高阶组件

    高阶组件(HOC)是React里的高级技术为了应对重用组件的逻辑.HOCs本质上不是React API的一部分.它是从React的组合性质中显露出来的模式. 具体来说,一个高阶组件就是一个获取一个组件 ...

  5. WCF技术剖析之二十四: ServiceDebugBehavior服务行为是如何实现异常的传播的?

    原文:WCF技术剖析之二十四: ServiceDebugBehavior服务行为是如何实现异常的传播的? 服务端只有抛出FaultException异常才能被正常地序列化成Fault消息,并实现向客户 ...

  6. 第三百二十四节,web爬虫,scrapy模块介绍与使用

    第三百二十四节,web爬虫,scrapy模块介绍与使用 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 其可以应用在数据挖掘,信息处理或存储历史数据等一系列的程序中.其最初是为了 ...

  7. FreeSql (二十四)Linq To Sql 语法使用介绍

    原本不支持 IQueryable 主要出于使用习惯的考虑,如果继承 IQueryable,编写代码的智能总会提示出现一堆你不想使用的方法(对不起,我有强迫症),IQueryable 自身提供了一堆没法 ...

  8. 设计模式学习(二十四):Spring 中使用到的设计模式

    设计模式学习(二十四):Spring 中使用到的设计模式 作者:Grey 原文地址: 博客园:设计模式学习(二十四):Spring 中使用到的设计模式 CSDN:设计模式学习(二十四):Spring ...

  9. Bootstrap<基础二十四> 缩略图

    Bootstrap 缩略图.大多数站点都需要在网格中布局图像.视频.文本等.Bootstrap 通过缩略图为此提供了一种简便的方式.使用 Bootstrap 创建缩略图的步骤如下: 在图像周围添加带有 ...

  10. 二十四、Struts2中的UI标签

    二十四.Struts2中的UI标签 Struts2中UI标签的优势: 数据回显 页面布局和排版(Freemark),struts2提供了一些常用的排版(主题:xhtml默认 simple ajax) ...

随机推荐

  1. laravel打印查询的sql

    public function __construct( ){ $log = DB :: listen( function( $sql ){ echo $sql; } ); }

  2. [fw]error: aggregate value used where an integer was expected

    一個自訂struct型態的變數,若想要轉換為unsigned,直接使用cast,gcc(version 4.4.3)編譯會回報錯誤. 例如: struct _test { unsigned hour ...

  3. L2Dwidget

    只需要在[页首html代码]中引入L2Dwidget.js即可.<!-- 右下角live2d效果 --> <script src="https://eqcn.ajz.mie ...

  4. 在Echarts区域的任何位置精准触发事件

    ​ 需求背景:点击Echarts区域跳转页面,跳转的区域不包括grid的坐标及标签,翻看了Echarts官网,实现触发事件之的on方法,但是此方法只能在鼠标点击某个图形上会触发,这样并不能实现需求.通 ...

  5. #Ubuntu16.0.4 LTS 安装RabbitMQ

    1.ubuntu下安装配置rabbitmq-server服务器环境:ubuntu16.0.4(向下兼容14.0.4)软件版本:RabbitMQ 3.7.5 .Erlang 20.1.7参考文档:htt ...

  6. Mac读写NTFS硬盘

    简明教程: 1.插上硬盘后,查看你的硬盘名称,这里假设名称是Untitled,牢记 2.在终端输入sudo nano /etc/fstab 敲击回车 3.现在你看到了一个编辑界面,输入LABEL=Un ...

  7. Harbor私有镜像仓库(下)

    Harbor私有镜像仓库(下) 链接:https://pan.baidu.com/s/1MAb0dllUwmoOk7TeVCZOVQ 提取码:ldt5 复制这段内容后打开百度网盘手机App,操作更方便 ...

  8. jQuery取值/赋值常见方法收集

    1.文本取值.赋值 $("#id").attr("value"); $("#id").val(); $("#id).attr(&q ...

  9. c++简单线程池实现(转)

    线程池,简单来说就是有一堆已经创建好的线程(最大数目一定),初始时他们都处于空闲状态,当有新的任务进来,从线程池中取出一个空闲的线程处理任务,然后当任务处理完成之后,该线程被重新放回到线程池中,供其他 ...

  10. 关于python全局变量

    今天踩了一个坑,记录一下,避免后犯 在constant.py 中定义了一个全局变量 ZH_LIST= [],以个用于存储配置一些信息: 在views.py 中引用了这个ZH_LIST : 然后在app ...