前后端分离的项目

>: 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框架之视图类的更多相关文章

  1. DRF介绍,DRF项目开发,DRF项目的视图类的dispatch源码解析

    目录 一.DRF介绍 1. 什么是DRF 2. 为什么要用DRF (1)使用DRF的原因 (2)站在开发者的角度来说用DRF的好处(暂时列举这么多) 二.用DRF开发后端项目 三.APIView请求生 ...

  2. 【DRF框架】视图组件

    基于mixins视图类 from rest_framework import mixins # 创建视图 class CreateModelMixin(object) def create(self, ...

  3. DRF框架之视图方法的几个封装好的模块介绍(第三天)

    1.DRF框架给我们封装好了好多层模块的 来实现简便接口的编写 # from rest_framework.mixins import CreateModelMixin, UpdateModelMix ...

  4. django drf框架中的user验证以及JWT拓展的介绍

    登录注册是几乎所有网站都需要去做的接口,而说到登录,自然也就涉及到验证以及用户登录状态保存,最近用DRF在做的一个关于网上商城的项目中,引入了一个拓展DRF JWT,专门用于做验证和用户状态保存.这个 ...

  5. DRF框架(二)——解析模块(parsers)、异常模块(exception_handler)、响应模块(Response)、三大序列化组件介绍、Serializer组件(序列化与反序列化使用)

    解析模块 为什么要配置解析模块 1)drf给我们提供了多种解析数据包方式的解析类 form-data/urlencoded/json 2)我们可以通过配置来控制前台提交的哪些格式的数据后台在解析,哪些 ...

  6. 第二章、drf框架 - 请求模块 | 渲染模块 解析模块 | 异常模块 | 响应模块 (详细版)

    目录 drf框架 - 请求模块 | 渲染模块 解析模块 | 异常模块 | 响应模块 Postman接口工具 drf框架 注册rest_framework drf框架风格 drf请求生命周期 请求模块 ...

  7. DRF框架 之基础配置

    Vue框架的总结 """ 1.vue如果控制html 在html中设置挂载点.导入vue.js环境.创建Vue对象与挂载点绑定 2.vue是渐进式js框架 3.vue指令 ...

  8. 3) drf 框架生命周期 请求模块 渲染模块 解析模块 自定义异常模块 响应模块(以及二次封装)

    一.DRF框架 1.安装 pip3 install djangorestframework 2.drf框架规矩的封装风格 按功能封装,drf下按不同功能不同文件,使用不同功能导入不同文件 from r ...

  9. drf框架 - 解析模块 | 异常模块 | 响应模块

    解析模块 为什么要配置解析模块 1)drf给我们提供了多种解析数据包方式的解析类 2)我们可以通过配置,来控制前台提交的哪些格式的数据后台在解析,哪些数据不解析 3)全局配置就是针对每一个视图类,局部 ...

随机推荐

  1. UIImage非正方形图片如何剪切为正方形

    有时候项目里做头像上传时候,必须要把用户从相册或是相机里的选择的图片剪切为指定大小的图片,遇到太大,太小或是太长的图片就需coregraphic来对图片进行剪切 废话不多说,直接上代码 /** * 剪 ...

  2. 第四周总结&实验报告二

    第四周总结&实验报告二 课程总结 这周我们学习了string类,以及很多string类的很多操作方法,同时string也是一个对象,在用到它时我们首字母需要大写,这周我们还加深了对函数构造的理 ...

  3. IView入门练习~CDN模式全局加载JS

    关于 iView iView 是一套基于 Vue.js 的开源 UI 组件库,主要服务于 PC 界面的中后台产品. 特性 高质量.功能丰富 友好的 API ,自由灵活地使用空间 细致.漂亮的 UI 事 ...

  4. 初识java虚拟机——JVM

    1.Java程序运行过程 编写 编译 运行 过程如图所示: 2.JVM的认识 定义:JVM是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚 ...

  5. 后盾网lavarel视频项目---2、phpstorm显示类中的方法快捷键

    后盾网lavarel视频项目---2.phpstorm显示类中的方法快捷键 一.总结 一句话总结: ctrl + f12 1.npm安装js插件? npm install hdjs 2.phpstor ...

  6. jvm内存模型学习心得

    昨天面试了两家,备受打击,问的多的就是jvm内存,然额真的是一头雾水.工作中用到的真是少之又少,面试还得问道, 今天恶补了下,在此作以下总结: jvm分为5部分 1.程序计数器 jvm支持多线程运行, ...

  7. Spring 缓存切面

    缓存切面:[通知+目标方法调用] 缓存操作执行过程: 1)如果是同步调用[sync=true],则首先尝试从缓存中读取数据,读取到则直接返回: 否则执行目标方法,将结果缓存后返回. 2)如果不是同步调 ...

  8. MVC、MVP 和 MVVM

    MVC Model–View–Controller 模型:管理应用程序的数据.逻辑和规则 视图:展示数据(可以直接从模型中获取数据) 控制器:接收输入并将其转化成模型和视图的命令 MVP Model– ...

  9. Advanced Message Queuing Protocol ( 1 ) 概述

    The Advanced Message Queuing Protocol (AMQP)是一个标准开放的应用层的消息中间件(Message Oriented Middleware)协议.AMQP定义了 ...

  10. 5.1.k8s.ConfigMap

    ConfigMap #ConfigMap用于保存配置数据的键值对,可用来保存单个属性,或配置文件 #ConfigMap创建 #使用yaml文件创建ConfigMap #cm-demo.yaml kin ...