Django框架(二十四)—— Django rest_framework-视图组件
视图组件
[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-视图组件的更多相关文章
- Django框架(十四)-- forms组件、局部钩子、全局钩子
一.什么是forms组件 forms组件就是一个类,可以检测前端传来的数据,是否合法. 例如,前端传来的邮箱数据,判断邮件格式对不对,用户名中不能以什么开头,等等 二.forms组件的使用 1.使用语 ...
- Django框架之第四篇(视图层)--HttpRequest对象、HttpResponse对象、JsonResponse、CBV和FBV、文件上传
视图层 一.视图函数 一个视图函数,简称视图,是一个简单的python函数,它接收web请求并且会返回web响应.响应可以是一张网页的html,一个重定向,或者是一张图片...任何东西都可以.无论是什 ...
- Django框架(十四)—— Django分页组件
目录 Django分页组件 一.分页器 二.分页器的使用 三.案例 1.模板层 2.视图层 Django分页组件 一.分页器 数据量大的话,可以分页获取,查看 例如:图书管理中,如果有成千上万本书,要 ...
- React文档(二十四)高阶组件
高阶组件(HOC)是React里的高级技术为了应对重用组件的逻辑.HOCs本质上不是React API的一部分.它是从React的组合性质中显露出来的模式. 具体来说,一个高阶组件就是一个获取一个组件 ...
- WCF技术剖析之二十四: ServiceDebugBehavior服务行为是如何实现异常的传播的?
原文:WCF技术剖析之二十四: ServiceDebugBehavior服务行为是如何实现异常的传播的? 服务端只有抛出FaultException异常才能被正常地序列化成Fault消息,并实现向客户 ...
- 第三百二十四节,web爬虫,scrapy模块介绍与使用
第三百二十四节,web爬虫,scrapy模块介绍与使用 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 其可以应用在数据挖掘,信息处理或存储历史数据等一系列的程序中.其最初是为了 ...
- FreeSql (二十四)Linq To Sql 语法使用介绍
原本不支持 IQueryable 主要出于使用习惯的考虑,如果继承 IQueryable,编写代码的智能总会提示出现一堆你不想使用的方法(对不起,我有强迫症),IQueryable 自身提供了一堆没法 ...
- 设计模式学习(二十四):Spring 中使用到的设计模式
设计模式学习(二十四):Spring 中使用到的设计模式 作者:Grey 原文地址: 博客园:设计模式学习(二十四):Spring 中使用到的设计模式 CSDN:设计模式学习(二十四):Spring ...
- Bootstrap<基础二十四> 缩略图
Bootstrap 缩略图.大多数站点都需要在网格中布局图像.视频.文本等.Bootstrap 通过缩略图为此提供了一种简便的方式.使用 Bootstrap 创建缩略图的步骤如下: 在图像周围添加带有 ...
- 二十四、Struts2中的UI标签
二十四.Struts2中的UI标签 Struts2中UI标签的优势: 数据回显 页面布局和排版(Freemark),struts2提供了一些常用的排版(主题:xhtml默认 simple ajax) ...
随机推荐
- python让人头大的装饰器...decorator带参不带参用法和原理.,..
0. 概念什么叫装饰器,其实也可以叫做包装器.即对于一个既有的函数func(args),在调用它之前和之后,我们希望都做一些事情,把这个函数包装起来. python中的装饰器分为两类:函数装饰器和类装 ...
- POJ1426-Find The Multiple-bfs
Given a positive integer n, write a program to find out a nonzero multiple m of n whose decimal repr ...
- python中变量的命令规制及变量的赋值方式
文章结构: 一.python中变量的命名规则 二.变量赋值的三种方式 三.python的垃圾回收机制 一.Python中变量的 ...
- Python之数字的格式化输出
需求: 将数字格式化后输出,并控制数字的位数.对齐.千位分隔符和其他的细节 x = 1234.56789 # Two decimal places of accuracy print(format(x ...
- 记一次CentOS7进单用户模式修改密码的失败经历(faild to load SELinux policy freezing)
背景:Cent SO7.4root用户密码忘记,根据https://www.linuxidc.com/Linux/2016-08/134034.htm提供的放法修改完密码之后系统启动后一直停留在转圈的 ...
- 【记录】mysql中建表utf8和utf8mb4区别?timestamp和datetime区别?
mysql中建表utf8和utf8mb4区别? 1:utf8 是 Mysql 中的一种字符集,只支持最长三个字节的 UTF-8字符,也就是 Unicode 中的基本多文本平面 2:要在 Mysql 中 ...
- sqlalchemy防sql注入
银行对安全性要求高,其中包括基本的mysql防注入,因此,记录下相关使用方法: 注意:sqlalchemy自带sql防注入,但是在 execute执行 手写sql时 需要考虑此安全问题 对于 wher ...
- org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute query; nested exception is org.hibernate.exception.SQLGrammarException: could not execute query
原因: 这个问题的解决方案很简单,主要是因为数据库中不存在相关的表或者列. org.springframework.dao.InvalidDataAccessApiUsageException: Pa ...
- 一、Gulp
开发和部署前端项目: 在开发Web应用中为加速客户端资源响应(js和css),减少对js和css的请求,通过bundles来实现. 在ASP.NET5中放弃该特性,被其他类似的组件所代替.比如使用Gu ...
- Web 请求之--性能相关
本博客代码运行环境 python : Python 3.7.1rc1 version pip : pip 19.1.1 version Scrapy: scrapy 1.6.0 version asy ...