前后端分离的项目

>: 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. oracle em启动问题

    这种情况出现的可能性是(1)主机IP地址改变,(2)主机名改变,(3)移植到全新的主机,(4)监听程序未启动,5)oracle服务也检查一下 关于orcl的启动: emctl start dbcons ...

  2. Html/CSS 示例演练 图书馆后台界面

    示例演练(html css javascript) --制作图书馆后台界面 1. 成品图

  3. hdu 4511 (AC自动机)

    注意标记一个点后,fail树上的子节点都会被标记 跑spfa,dp也可以 #include<iostream> #include<cstdio> #include<str ...

  4. robotframework json解析

    用robotframework做接口测试,现在用的最多的就是json格式的数据,刚开始接触会感觉一脸懵逼,不知道怎么去取里面的值.在这里简单介绍一下,其实本身json取值不会太难,只要理解层次关系,一 ...

  5. centos6.5+jdk1.7+mysql5.6+tomcat8.0部署jpress

    前言:此篇记录在linux下搭建环境部署jpress,mysql使用的是源码安装 1.准备 2.安装 3.部署 1.准备 a.准备centos6.5服务器环境 mysql-5.6.19.tar.gz  ...

  6. php7.2 下安装yaf扩展

    wget http://pecl.php.net/get/yaf-3.0.7.tgz  解压并进入目录: 1 tar -zxvf yaf-3.0.7* && cd yaf-3.0.7  ...

  7. 【HANA系列】SAP HANA STUDIO客户端升级更新

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列]SAP HANA STUDIO客 ...

  8. 【Linux开发】如何更改linux文件的拥有者及用户组(chown和chgrp)

    本文整理自: http://blog.163.com/yanenshun@126/blog/static/128388169201203011157308/ http://ydlmlh.iteye.c ...

  9. java 多线程并发问题总结

    java 多线程并发主要通过关键字synchronized实现 Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 一.当两个并发线程访问 ...

  10. 如何上传大文件到github上

    真的是被百度坑怕了,只适合我自己的 如果你之前安装git成功的话,右键会出现两个新选项,分别为Git Gui Here,Git Bash Here,这里我们选择Git Bash Here,进入如下界面 ...