一、基本视图

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框架 之 admin管理工具(组件使用)

    Django框架 之 admin管理工具(组件使用) 浏览目录 激活管理工具 使用管理工具 admin的定制 admin组件使用 Django 提供了基于 web 的管理工具. Django 自动管理 ...

  2. django框架<二>

    django框架:   Models 1.基本创建 Django提供了一个抽象层("Model")的构建和管理Web应用程序的数据. Django使用一种新的方式,即:关系对象映射 ...

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

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

  4. Django框架第九篇--Django和Ajax、序列化组件(serializers)、自定义分页器、模型表choice参数

    Django和Ajax 一.什么是Ajax AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”.即使用Javascript语 ...

  5. Django框架(十五)—— forms组件、局部钩子、全局钩子

    目录 forms组件.局部钩子.全局钩子 一.什么是forms组件 二.forms组件的使用 1.使用语法 2.组件的参数 3.注意点 三.渲染模板 四.渲染错误信息 五.局部钩子 1.什么是局部钩子 ...

  6. Django框架(二) MTV模型简介

    MTV模型 Django的MTV分别代表 Model(模型):和数据库相关的,负责业务对象与数据库的对象(ORM) Template(模板):放所有的html文件 模板语法:目的是将白变量(数据库的内 ...

  7. Django框架(二)

    一:Django项目创建步骤: 方式1:命令创建: 进入指定目录 C:\Users\bing>F: F:\>cd mysite F:\mysite>django-admin star ...

  8. Django框架(十三)--Django分页组件

    一.分页器 数据量大的话,可以分页获取,查看 例如:图书管理中,如果有成千上万本书,要是都在一个页面中渲染出来,会影响页面美观,所以就要用分页器分页渲染 二.分页器的使用 基本写法 基本写法: 后端: ...

  9. Django框架(十三)——Auth模块

    Auth模块 一.什么是auth模块 Auth模块是Django自带的用户认证模块 Auth模块是Django自带的用户认证模块,可以实现包括用户注册.用户登录.用户认证.注销.修改密码等功能.默认使 ...

  10. 潭州课堂25班:Ph201805201 django框架 第十三课 自定义404页面,auth系统中的User模型,auth系统权限管理 (课堂笔记)

    当 DEBUG=True 时,django 内部的404报错信息, 自带的报错信息, 要自定义404信息,要先把 DEBUG=False , 之后要自定义4040页面,有两种方法, 方法1,在创建40 ...

随机推荐

  1. Webshell篇

    常用方法简介: 一.0day拿webshell 参考工具:织梦漏洞利用小工具 二.通过注入漏洞拿Webshell 前提条件:具有足够权限,对写入木马的文件夹要有写入权限,知道网站绝对路径. 对于mss ...

  2. ACM-ICPC 2018 沈阳赛区网络预赛 J. Ka Chang(树上分块+dfs序+线段树)

    题意 链接:https://nanti.jisuanke.com/t/A1998 给出一个有根树(根是1),有n个结点.初始的时候每个结点的值都是0.下面有q个操作,操作有两种,操作1.将深度为L(根 ...

  3. fiddler---Fiddler性能测试

    从上几篇文章中我们了解到Fiddler可以帮助我们做接口测试,修改断点,抓包等应用,但是你可能想想不到,Fiddler也能做简单的性能测试 性能测试 性能测试是通过自动化的测试工具模拟多种正常.峰值以 ...

  4. luoguP3531 [POI2012]LIT-Letters

    (https://www.luogu.org/problem/P3531) 注意编号 #include<cstdio> #include<algorithm> #include ...

  5. 毕业设计代做,各种系统微服务项目ssm项目,员工管理系统,微信小程序,购物商城,二手商城系统,销售系统,等等

    毕业设计代做,各种系统,微服务项目,ssm项目 小程序,商城等,期末作业等都可以,价格好说,长期接单, 有项目说明书,软件介绍相关文档,答辩的时候包过,知识点对接好,给你讲解等, 毕业设计代做,各种系 ...

  6. 【转】基于Bootstrap的超酷jQuery开关按钮插件

    基于Bootstrap的超酷jQuery开关按钮插件

  7. Markdown & LaTex 常用语法

    目录 blog 的目录 博客园自带目录 用 javascript 自定义目录 主标题 副标题 h1,一级标题 h2,二级标题 h3,三级标题 注释 常用的符号及文本形式 如果你想在markdown中文 ...

  8. 如何编写一个 SendFile 服务器

    如何编写一个 SendFile 服务器 前言 之前讨论零拷贝的时候,我们知道,两台机器之间传输文件,最快的方式就是 send file,众所周知,在 Java 中,该技术对应的则是 FileChann ...

  9. 详解 IaaS、PaaS和SaaS 以及他们各自的代表公司

    ——IaaS,PaaS和SaaS 是云计算领域的专业术语,也是云计算的三种服务模式.   (1)SaaS:Software as a Service,软件即服务(也称为云应用程序服务) . 云市场中企 ...

  10. Allure自动化测试报告我是这样用的

    关于自动化测试报告: 之前用过testNG自带的测试报告.优化过reportNG的测试报告.extentreport.Zreport(大飞总原创),这些是我之前都用过的,也是在去年雯姐和我说过Allu ...