前后端分离的项目

>: 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. 关于tomcat的server.xml里host节点配置的一些说明

    其实对这个一直搞不清楚,后来公司的网站遭遇与IIS进行整合,然后上面有几个应用需要进行配置,所以对tomcat的server.xml进行了一些深入的了解 Host的节点主要是起一个对域名解析到那个虚拟 ...

  2. #学号 20175201张驰 《Java程序设计》第10周课下作业MyList

    参见附件,补充MyList.java的内容,提交运行结果截图(全屏) 课下推送代码到码云 public class MyList { public static void main(String [] ...

  3. 2018-2019-2 网络对抗技术 20165220 Exp 9 Web安全基础

    2018-2019-2 网络对抗技术 20165220 Exp 9 Web安全基础 实验任务 本实践的目标理解常用网络攻击技术的基本原理,做不少于7个题目,共3.5分.包括(SQL,XSS,CSRF) ...

  4. 十四、RF中SSHLibrary库介绍

    A.安装SSHLibrary:   pip2 install robotframework-sshlibrary   (导入SSHLibrary) B.远程连接linux服务器 1.#连接linux服 ...

  5. 浏览器端-W3School:HTML DOM cells 集合

    ylbtech-浏览器端-W3School:HTML DOM cells 集合 1.返回顶部 1. HTML DOM cells 集合 HTML DOM Table 对象 定义和用法 cells 集合 ...

  6. EDM案例讲解:Mouth foods的EDM邮件营销

    你可能没有听说过Mouth foods,它是一个美味产品的在线市场.作为一个日益增长的企业,他们知道电子邮件的重要性,因为在此之前他们通过电子邮件真正找到了企业品牌中的自我,这就是为什么他们认为电子邮 ...

  7. ArcCatalog连接远程ArcGIS Server服务器

    注意:本地机器登陆的用户名和密码必须与ArcGIS Server服务器上的用户名和密码完全一致,并加入到agsadmin和agsuser组中.重启电脑.   (其实就是在自己的电脑上建立一个用户名,这 ...

  8. Django 自带 user 字段扩展及头像上传

    django 及 rest_framework 笔记链接如下: django 入门笔记:环境及项目搭建 django 入门笔记:数据模型 django 入门笔记:视图及模版 django 入门笔记:A ...

  9. 【FICO系列】SAP FICO-模块 关于固定资产年结和折旧的问题

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[FICO系列]SAP FICO-模块 关于固定 ...

  10. Java——LinkedHashMap源码解析

    以下针对JDK 1.8版本中的LinkedHashMap进行分析. 对于HashMap的源码解析,可阅读Java--HashMap源码解析 概述   哈希表和链表基于Map接口的实现,其具有可预测的迭 ...