DRF框架之视图类
前后端分离的项目
>: pip3 install djangorestframework
一.视图类传递参数给序列化类
视图层:views.py
需求:
(1)在视图类中实列化对象是,可以设置context的传递内容
(2)也就是在哪里可以得到或者这个context的局部钩子,全局钩子,create. update 方法中, 都可以用 self.,context 访问视图
类传递过来的内容
如:我们在视图类中可以通过request得到登录用户reqest.user
(2)再续列化中,要完成数据的奇校验入库操作,可能需要知道的是当前登录的用户,但是序列化类是无法访问request的
(3)数据的存放方法 在视图类中序列化对象时,可以将reqeust的对象传递过去
如果是异常的捕获 response =None Djagno 源码中不不会帮我们进行捕获
from rest_framework.views import exception_handler as drf_exception_handler
from rest_framework.views import Response
from rest_framework import status
def exception_handler(exc, context):
# drf的exception_handler做基础处理
response = drf_exception_handler(exc, context)
# 为空,自定义二次处理
if response is None:
print('%s - %s - %s' % (context['view'], context['request'].method, exc))
return Response({
'detail': '服务器错误'
}, status=status.HTTP_500_INTERNAL_SERVER_ERROR, exception=True)
return response
路由的匹配
url(r"^vv/books/$", views.MyRequest.as_view()),
url(r'^vv/books/(?P<pk>.*)/$', views.MyRequest.as_view())
view 视图的代码
class MyRequest(APIView):
def post(self, request, *args, **kwargs):
request_data = request.data # book_ser 序列化数据对象
book_data = serializers.BookModelSerializer(data=request_data, many=False, context={"request": request})
# 进行数据的检验
book_data.is_valid(raise_exception=True)
result_data = book_data.save()
return APIResponse(results=result_data) # 直接封装 create() 的话要进行many = True
#
局部钩子需要的检验的数据
from rest_framework.serializers import ModelSerializer,SerializerMethodField
from rest_framework.serializers import ListSerializer
from rest_framework.exceptions import ValidationError
from . import models # 重写我们update() 方法 # 重点将我们ListSerializer() class BookListSerializer(ListSerializer): def update(self, instance, validated_data):
print(instance,111) # [<Book: <东游记9988>>, <Book: <西游记999>>, <Book: <南游记>>]
print(validated_data,2222)
# [{'name': '东游记88', 'price': Decimal('66.66')}, {'name': '西游记999',
# 'price': Decimal('77.88')}, {'name': '南游记', 'price': Decimal('8.88')}]
# 获取里面的所有数据
print(self.child,12312312)
for index, obj in enumerate(instance):
# 获取对象的索引和下标
self.child.update(obj,validated_data[index])
return instance # 返回对象 class BookModelSerializer(ModelSerializer):
class Meta:
model = models.Book
# 映射
fields = ('name','price', 'img','author_list', 'publish_name','publisher','authors')
extra_kwargs = {
'name':{
'required':True,
'min_length':3,
'error_messages':{ 'required':'必填字段',
'min_length':'不能少于3位数字'
}
},
'publisher':{
'write_only':True,
},
'authors':{
'write_only': True
},
'img':{
'read_only':True, },
'author_list':{
'read_only':True
},
'publish_name':{
'read_only':True
}
} # patch()方法是用save()
# 方法进行数据的更新 但是没有进行update()方法的封装 需要我们自己 重写update() 方法
list_serializer_class = BookListSerializer
# 局部勾子和全局钩子
def validate_name(self,value):
# 书名不能有'is'字符
print(self.context,1111)
if 'k' in value: # ???
raise ValidationError('该k书不能出版')
return value # 全局钩子
def validate(self, attrs):
publisher = attrs.get('publisher')
name = attrs.get('name')
if models.Book.objects.filter(name=name,publisher=publisher):
raise ValidationError({'book':'该书已经存在'})
return attrs
二.二次封装我们的response
路由
from django.conf.urls import url
from api import views urlpatterns = [ url(r'^books/$',views.V2Book.as_view()),
url(r'^books/(?P<pk>.*)/$',views.V2Book.as_view()),
url(r"^v1/books/$",views.BookApIView.as_view()), ]
views 代码
# 重写response() 响应方法
class BookApIView(APIView):
def get(self,*args, **kwargs):
book_query = models.Book.objects.filter(is_delete=False).all()
book_ser = serializers.BookModelSerializer(book_query,many=True)
# print(book_ser)
book_data = book_ser.data # 数据是存放在data 中的
# print(book_data)
# 返回数据我们用封装号的
return APIResponse(results=book_data)
utils 文件中重写response 方法继承super()
# 我们自定义
from rest_framework.response import Response class APIResponse(Response):
def __init__(self, data_status=1,data_msg='ok',
results=None,http_status=None, headers=None,exception=False,*kwargs): # 我们需要返回的值
# data的初始信息:
data = {
'status':data_status,
'msg':data_msg,
}
# data的响应数据体
# results 响应可能是False 0等数据 这些数据在我们设计的方法下是不合法的所以要进行过滤
if results is not None:
data['results'] = results
# 将请求后的字典内容进行更新 有则
data.update(kwargs)
super().__init__(data=data,status=http_status,headers=headers,exception=exception)
三.视图家族
"""
views:视图
generics:工具视图
mixins:视图工具集
viewsets:视图集
"""
"""
学习曲线
APIView => GenericAPIView => mixins的五大工具类 => generics中的工具视图 => viewsets中的视图集
"""
数据的返回
3.1 GenericAPIView基类
# GenericAPIView是继承APIView的,使用完全兼容APIView
# 重点:GenericAPIView在APIView基础上完成了哪些事
# 1)get_queryset():从类属性queryset中获得model的queryset数据
# 2)get_object():从类属性queryset中获得model的queryset数据,再通过有名分组pk确定唯一操作对象
# 3)get_serializer():从类属性serializer_class中获得serializer的序列化类
路由
url(r"^v2/books/$", views.BookGenericAPIView.as_view()),
url(r'^v2/books/(?P<pk>.*)/$', views.BookGenericAPIView.as_view()),
实列一
# Genseric 类
from rest_framework.generics import GenericAPIView class BookGenericAPIView(GenericAPIView):
# 因为我们继承的是GenericAPIView >>> 继承APIView
# queryset = None 和serializer = None 初始值为空时需要我们进行重写的
queryset = models.Book.objects.filter(is_delete=False) serializer_class = serializers.BookModelSerializer # 单查 pk get的方法 lookup_field = 'pk' # def get(self, request, *args, **kwargs):
# book_query = self.get_object()
# print(book_query, 55)
# book_ser = self.get_serializer(book_query)
# book_data = book_ser.data
# return APIResponse(results=book_data) # 群查
def get(self, request, *args, **kwargs):
book_query = self.get_queryset()
book_ser = self.get_serializer(book_query,many=True) # 这里加上many=True
book_data = book_ser.data
return APIResponse(results=book_data)
get的方法单查和全查
# mixins 有五大工具六大方法
from rest_framework.mixins import ListModelMixin,CreateModelMixin,RetrieveModelMixin,UpdateModelMixin class BookMixinGenericAPIView(ListModelMixin,CreateModelMixin,UpdateModelMixin,RetrieveModelMixin,GenericAPIView):
# 先获取对象
queryset = models.Book.objects.filter(is_delete=False)
# 重写序列化
serializer_class = serializers.BookModelSerializer def get(self,request,*args, **kwargs):
# mixins 中的单查 pk
if 'pk' in kwargs: response = self.retrieve(request,*args,**kwargs)
else:
# mixins提供的list方法的响应对象是Response,想将该对象格式化为APIResponse
response = self.list(request, *args, **kwargs)
# 数据都是封装在response return APIResponse(results=response.data)
post /put/patch/
# 单增post 多增的操作
def post(self, request, *args, **kwargs):
response = self.create(request, *args, **kwargs)
return APIResponse(results=response.data) # =更新put
# 注意必须在pk = 22 有值的情况 也必须是在url 中拼接pk 才能进行目前的修改
def put(self,request, *args, **kwargs):
response = self.update(request, *args, **kwargs)
return APIResponse(results=response.data) # patch修改 也会需要 pk url 中拼接 局部跟新和整体更新,partial=True
def patch(self,request, *args, **kwargs):
response = self.update(request, *args, **kwargs)
return APIRsponse(response.data)
四.mixins视图工具集 - 辅助GenericAPIView
# 1)工具视图都是GenericAPIView的子类,且不同的子类继承了不听的工具类,重写了请求方法
# 2)工具视图的功能如果直接可以满足需求,只需要继承工具视图,提供queryset与serializer_class即可
# 工具视图
"""
# 1)工具视图都是GenericAPIView的子类,且不同的子类继承了不听的工具类,重写了请求方法
# 2)工具视图的功能如果直接可以满足需求,只需要继承工具视图,提供queryset与serializer_class即可
"""
# 群查 局部更新 from rest_framework.generics import ListCreateAPIView,UpdateAPIView
class BookListCreateAPIView(ListCreateAPIView, UpdateAPIView):
queryset = models.Book.objects.filter(is_delete=False)
serializer_class = serializers.BookModelSerializer
五.GenericAPIView 与 APIView 最为两大继承视图的区别
# 1)GenericViewSet和ViewSet都继承了ViewSetMixin,as_view都可以配置 请求-函数 映射
# 2)GenericViewSet继承的是GenericAPIView视图类,用来完成标准的 model 类操作接口
# 3)ViewSet继承的是APIView视图类,用来完成不需要 model 类参与,或是非标准的 model 类操作接口
# post请求在标准的 model 类操作下就是新增接口,登陆的post不满足
# post请求验证码的接口,不需要 model 类的参与
# 案例:登陆的post请求,并不是完成数据的新增,只是用post提交数据,得到的结果也不是登陆的用户信息,而是登陆的认证信息
s视图集
# 视图集..set
"""
(1)优先继承ViewSetMixin 类 再继承一个视图类(GenericViewSet 和APIView)
(2)ViewSetMixin提供重写ad_view() 方法 ,继承视图集的属兔类,-匹配路由调用da_view() 必须出入对饮的映射关系as_view("get":"my_get_list")
"""
from rest_framework.viewsets import GenericViewSet # 视图集中导入视图类
from rest_framework import mixins # 工具类 class BookGenericViewSet(mixins.RetrieveModelMixin, mixins.ListModelMixin, GenericViewSet):
queryset = models.Book.objects.filter(is_delete=False)
serializer_class = serializers.BookModelSerializer
# 群查
def my_get_list(self,request,*args, **kwargs):
return self.list(request, *args, **kwargs)
# 单查
def my_get_obj(self, request,*args, **kwargs):
return self.retrieve(request, *args, **kwargs)
mixin的五大工具六大方法
# 路由模块:为标准的viewset接口提供路径简写的方式
from django.conf.urls import include
from rest_framework.routers import SimpleRouter
router = SimpleRouter()
router.register('v6/books', views.BookModelViewSet)
# url(r'^v6/books/$', views.BookModelViewSet.as_view({'get': 'list', 'post': 'create'})),
# url(r'^v6/books/(?P<pk>.*)/$', views.BookModelViewSet.as_view({'get': 'retrieve', 'put': 'update', 'patch': 'partial_update', 'delete': 'destroy'})), url(r'^', include(router.urls)) 六.终极写法 六大方法(*****)
路由的代码
url(r'^v7/books/$',views.BookModelViewSet.as_view({"get":'list','post':'create'})),
url(r'^v7/books/(?P<pk>.*)/$',views.BookModelViewSet.as_view({'get':'retrieve','put':'update','patch':'partial_update','delete':'destroy'})),
view 视图代码
# 拥有就打接口:单查/群查/单增/ 单删/单整体改/单局部改
# 补充:一般肯定需要我们重写destroy 方法
""" class ModelViewSet(mixins.CreateModelMixin,
mixins.RetrieveModelMixin,
mixins.UpdateModelMixin,
mixins.DestroyModelMixin,
mixins.ListModelMixin,
GenericViewSet): # 继承这个主要是让他遵循我们自己写的as_view({"get":"list",'patch':"partial_update",'put':"update","post":"create", "destroy":'destroy'})
"""
# 继承的模块类ModelViewSet
from rest_framework.viewsets import ModelViewSet class BookModelViewSet(ModelViewSet):
queryset = models.Book.objects.filter(is_delete=False)
serializer_class = serializers.BookModelSerializer
"""
as_view({"get":'list','post':'create'})
get >>>list 群查 post >>> 新增
as_view({'get':'retrieve','put':'update','patch':'partial_update','delete':'destroy'}
get >>>retrieve 单查 提供pk在url put >>> partial = False不能进单个字段的修改 而是整体字段的更新
patch >>>> partial_update 默认partial = True,
"""
# 一般我们删除的不是真正的数据 而是将他的bOOL 改为1 /获取是Treu
# 除了删除需要我们自己写 因为 特会将正真的数据进行删除肯定不合理 所以我们自己写优先走我们自己的 def destroy(self, request, *args, **kwargs):
instance = self.get_object() # 单删 实列化对象
if not instance: # 改实例对象不存在
return APIResponse(0, '删除失败')
instance.is_delete = True
instance.save()
return APIResponse(1,'删除成功')
DRF框架之视图类的更多相关文章
- DRF介绍,DRF项目开发,DRF项目的视图类的dispatch源码解析
目录 一.DRF介绍 1. 什么是DRF 2. 为什么要用DRF (1)使用DRF的原因 (2)站在开发者的角度来说用DRF的好处(暂时列举这么多) 二.用DRF开发后端项目 三.APIView请求生 ...
- 【DRF框架】视图组件
基于mixins视图类 from rest_framework import mixins # 创建视图 class CreateModelMixin(object) def create(self, ...
- DRF框架之视图方法的几个封装好的模块介绍(第三天)
1.DRF框架给我们封装好了好多层模块的 来实现简便接口的编写 # from rest_framework.mixins import CreateModelMixin, UpdateModelMix ...
- django drf框架中的user验证以及JWT拓展的介绍
登录注册是几乎所有网站都需要去做的接口,而说到登录,自然也就涉及到验证以及用户登录状态保存,最近用DRF在做的一个关于网上商城的项目中,引入了一个拓展DRF JWT,专门用于做验证和用户状态保存.这个 ...
- DRF框架(二)——解析模块(parsers)、异常模块(exception_handler)、响应模块(Response)、三大序列化组件介绍、Serializer组件(序列化与反序列化使用)
解析模块 为什么要配置解析模块 1)drf给我们提供了多种解析数据包方式的解析类 form-data/urlencoded/json 2)我们可以通过配置来控制前台提交的哪些格式的数据后台在解析,哪些 ...
- 第二章、drf框架 - 请求模块 | 渲染模块 解析模块 | 异常模块 | 响应模块 (详细版)
目录 drf框架 - 请求模块 | 渲染模块 解析模块 | 异常模块 | 响应模块 Postman接口工具 drf框架 注册rest_framework drf框架风格 drf请求生命周期 请求模块 ...
- DRF框架 之基础配置
Vue框架的总结 """ 1.vue如果控制html 在html中设置挂载点.导入vue.js环境.创建Vue对象与挂载点绑定 2.vue是渐进式js框架 3.vue指令 ...
- 3) drf 框架生命周期 请求模块 渲染模块 解析模块 自定义异常模块 响应模块(以及二次封装)
一.DRF框架 1.安装 pip3 install djangorestframework 2.drf框架规矩的封装风格 按功能封装,drf下按不同功能不同文件,使用不同功能导入不同文件 from r ...
- drf框架 - 解析模块 | 异常模块 | 响应模块
解析模块 为什么要配置解析模块 1)drf给我们提供了多种解析数据包方式的解析类 2)我们可以通过配置,来控制前台提交的哪些格式的数据后台在解析,哪些数据不解析 3)全局配置就是针对每一个视图类,局部 ...
随机推荐
- Jar包方式运行web项目
使用Maven进行打包 在自己的电脑终端中进入到pom.xml文件的目录中执行maven打包.命令为: mvn clean package 1 成功的标志为上面显示BUILD SUCCESS成功打包 ...
- 5.并发编程-synchronized 细节说明
并发编程-synchronized 细节说明 1. synchronized-锁重入 & 异常释放锁 说明 * 关键字synchronized 拥有锁重入的功能,也就是在使用synchroni ...
- Oracle开发:常用的数据库字段类型[转]
Oracle常用的数据库字段类型如下: 字段类型 中文说明 限制条件 其它说明 CHAR 固定长度字符串 最大长度2000 bytes VARCHAR2 可变长度的字符串 最大长度4000 bytes ...
- 初识linux命令
1. type: 查看是外部命令/内部命令 外部命令 有存放地址信息 内部命令 is a shell builtin 2.file 查看文件的编码方式 file /sbin/ifconfig 编译执行 ...
- js测试用
一,大纲 二,目录二 三,目录三
- vmware fusion 找不到可以连接的有效对等进程
红框会有什么提示 vmware...,你点击允许
- 测开之路一百四十三:ORM框架之SQLAlchemy模型及表创建
基于前一篇内容,可以使用模型的结构 目录结构 main,入口层 from flask import Flaskfrom flask_sqlalchemy import SQLAlchemy app = ...
- oracle ogg 单实例单向简单搭建测试(oracle-oracle)
昨天突然接到消息说有一个线上的ogg出现了问题,看是否能修复,由于ogg以前玩的少,所以就加急搞了个测试环境,练习了一把 环境 db1,db2(单实例)ip: 1*,1*sid: orcl,ogg1o ...
- 通俗易懂的理解 Redux(知乎)
1. React有props和state: props意味着父级分发下来的属性[父组件的state传递给子组件 子组件使用props获取],state意味着组件内部可以自行管理的状态,并且整个Rea ...
- 【Qt开发】QT样式表单 qss的样式优化
QT样式表单 QT的样式表单允许我们在对程序不做任何代码上的更改的情况下轻松改变应用程序的外观. 其思想来源于网页设计中的CSS,即可以将功能设计和美学设计分开. 它的语法和概念和HTML CSS也是 ...