一、基本视图

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. [日常] 神奇的引导问题deepin与win10

    经过昨天的一番折腾,我的电脑一开机就可以进入deepin的引导界面,也可以登录到deepin,但是访问windows直接报错.我的windows已经使用PE安装完了win10,还是打不开. 当我在研究 ...

  2. xml的建模

    xml建模的思路 1.分析需要被建模的文件中有那几个对象 2.每个对象拥有的行为以及属性 3.定义对象从小到大(从里到外) 4.通过23种的设计模式中的工厂模式,解析xml生产出指定对象 建模的好处 ...

  3. 使用响应的json数据判断订单查询是否成功;

    #查询中通快递import requestsrr=requests.session()headers={"User-Agent": "Mozilla/5.0 (Windo ...

  4. 4.web基础$_POST

  5. 剑指Offer-2.替换空格(C++/Java)

    题目: 请实现一个函数,将一个字符串中的每个空格替换成“%20”.例如,当字符串为We Are Happy.则经过替换之后的字符串为We%20Are%20Happy. 分析: 题意明确,就是将一个字符 ...

  6. cicros安装

    1.下载与安装依赖包 wget https://github.com/libgd/libgd/releases/download/gd-2.2.5/libgd-2.2.5.tar.gz tar zxv ...

  7. 深挖计算机基础:Linux性能优化学习笔记

    参考极客时间专栏<Linux性能优化实战>学习笔记 一.CPU性能:13讲 Linux性能优化实战学习笔记:第二讲 Linux性能优化实战学习笔记:第三讲 Linux性能优化实战学习笔记: ...

  8. hex2pcap

    #include <stdlib.h> #include <stdio.h> #include <string.h> typedef struct { unsign ...

  9. 剑指offer:对称的二叉树(镜像,递归,非递归DFS栈+BFS队列)

    1. 题目描述 /** 请实现一个函数,用来判断一颗二叉树是不是对称的. 注意,如果一个二叉树同此二叉树的镜像是同样的,定义其为对称的 */ 2. 递归 思路: /** 1.只要pRoot.left和 ...

  10. flink 注册函数示例

    需求 (filter): 现在有这么一个需求,统计出现在纽约的行车记录.这里我们需要进行一个过滤的操作,我们需要有个自定义的 UDF ,具体思路是,表里面有经度和维度这两个字段,通过这个可以来开发一个 ...