Django框架(二十三)-- Django rest_framework-视图组件
一、基本视图
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框架 之 admin管理工具(组件使用)
Django框架 之 admin管理工具(组件使用) 浏览目录 激活管理工具 使用管理工具 admin的定制 admin组件使用 Django 提供了基于 web 的管理工具. Django 自动管理 ...
- django框架<二>
django框架: Models 1.基本创建 Django提供了一个抽象层("Model")的构建和管理Web应用程序的数据. Django使用一种新的方式,即:关系对象映射 ...
- Django框架(十四)-- forms组件、局部钩子、全局钩子
一.什么是forms组件 forms组件就是一个类,可以检测前端传来的数据,是否合法. 例如,前端传来的邮箱数据,判断邮件格式对不对,用户名中不能以什么开头,等等 二.forms组件的使用 1.使用语 ...
- Django框架第九篇--Django和Ajax、序列化组件(serializers)、自定义分页器、模型表choice参数
Django和Ajax 一.什么是Ajax AJAX(Asynchronous Javascript And XML)翻译成中文就是“异步的Javascript和XML”.即使用Javascript语 ...
- Django框架(十五)—— forms组件、局部钩子、全局钩子
目录 forms组件.局部钩子.全局钩子 一.什么是forms组件 二.forms组件的使用 1.使用语法 2.组件的参数 3.注意点 三.渲染模板 四.渲染错误信息 五.局部钩子 1.什么是局部钩子 ...
- Django框架(二) MTV模型简介
MTV模型 Django的MTV分别代表 Model(模型):和数据库相关的,负责业务对象与数据库的对象(ORM) Template(模板):放所有的html文件 模板语法:目的是将白变量(数据库的内 ...
- Django框架(二)
一:Django项目创建步骤: 方式1:命令创建: 进入指定目录 C:\Users\bing>F: F:\>cd mysite F:\mysite>django-admin star ...
- Django框架(十三)--Django分页组件
一.分页器 数据量大的话,可以分页获取,查看 例如:图书管理中,如果有成千上万本书,要是都在一个页面中渲染出来,会影响页面美观,所以就要用分页器分页渲染 二.分页器的使用 基本写法 基本写法: 后端: ...
- Django框架(十三)——Auth模块
Auth模块 一.什么是auth模块 Auth模块是Django自带的用户认证模块 Auth模块是Django自带的用户认证模块,可以实现包括用户注册.用户登录.用户认证.注销.修改密码等功能.默认使 ...
- 潭州课堂25班:Ph201805201 django框架 第十三课 自定义404页面,auth系统中的User模型,auth系统权限管理 (课堂笔记)
当 DEBUG=True 时,django 内部的404报错信息, 自带的报错信息, 要自定义404信息,要先把 DEBUG=False , 之后要自定义4040页面,有两种方法, 方法1,在创建40 ...
随机推荐
- springboot 使用 jedis 连接 Redis 数据库
1. 在 pom.xml 配置文件中添加依赖 <!-- redis 依赖 --> <dependency> <groupId>org.springframework ...
- Centos的启动流程学习
Centos 6 的启动流程: POST ---> Boot sequence(BOIS) ---> Boot loader (MBR) ---> kernel(ramdiskfs ...
- 剑指Offer-14.链表中倒数第k个结点(C++/Java)
题目: 输入一个链表,输出该链表中倒数第k个结点. 分析: 第一个解法,我们可以先遍历一遍链表,计算下节点的总数n,然后再从头结点查n-k个节点,即是倒数第k个节点. 第二个解法,便是使用双指针,两个 ...
- luoguP2480 [SDOI2010]古代猪文
题意 考虑所求即为:\(G^{\sum\limits_{d|n}C_n^d}\%999911659\). 发现系数很大,先用欧拉定理化简系数:\(G^{\sum\limits_{d|n}C_n^d\% ...
- ini_set()
ini_set ( string $varname , string $newvalue ) : string 设置指定配置选项的值.这个选项会在脚本运行时保持新的值,并在脚本结束时恢复. 参数 va ...
- [LeetCode] 238. Product of Array Except Self 除本身之外的数组之积
Given an array nums of n integers where n > 1, return an array output such that output[i] is equ ...
- ICP 匹配定位算法学习记录
icp 算法原理是: 选取目标点云P和源点云Q,按照一定的约束条件,找到最邻近点(pi,qi),然后计算出最优R和t(旋转和平移), 使得误差函数最小,误差函数E(R,t): 基本算法流程: 1.在目 ...
- python接口自动化3-发送post及其他请求
前言 发过get请求相信学习post请求也很快学会,无非就是多了传参时的类型与参数格式.在我常见的post请求中用到最多的是json格式,但也有用其它,下面将介绍常用的参数类型格式. 一.Post请求 ...
- redis延迟队列
异步消息队列 Redis 的 list(列表) 数据结构常用来作为异步消息队列使用,使用rpush/lpush操作入队列, 使用 lpop 和 rpop 来出队列. > rpush notify ...
- python threading Semaphore
#Semaphore 是用于控制进入数量的锁,控制同时进行的线程,内部是基于Condition来进行实现的 #文件, 读.写, 写一般只是用于一个线程写,读可以允许有多个 #做爬虫 import th ...