1.APIView
1.1 当类视图不继承Django自带的View类,而继承DRF的APIView类(或其子类)时,APIView会为
这个类视图提供如下功能:
1.1.1 继承APIView的视图类具备View的所有特性
1.1.2 提取请求字符串参数的request.query_parms方法
1.1.3 请求体参数的request.data方法
1.1.4 APIView为视图类提供了认证,授权,限流等功能
2.Requset对象
2.1 request.query_parms:
可以获取到前端的查询字符串参数
2.2. request.data:
2.2.1.可以获取到请求体参数,兼容参数格式:
application/json:json格式数据
x-www-form-urlencoded:表单数据
multipart-form-data:html文本等格式数据
2.2.2.可以兼容获取到get,post,put,delete,patch等请求方法的参数
3.Response对象
3.1还会提供Response对象,代替继承View类的JsonResponse对象
3.2 在DRF中Response为HTTPResponse的子类
3.3 data参数为序列化之后的数据(字典/嵌套字典的列表)
3.4 会自动根据渲染器来将数据转化为请求头中Accept需要的格式进行返回
3.5 status参数指定响应状态码
3.6 content-type指定响应头中的Content-Type,一般无需指定,会根据渲染器来自动设置
3.2 提供api管理的html页面
4.parser解析器类
4.1 DRF中的解析器可以根据请求头中的Content-Type来自动解析参数,使用统一的data属性可以获取到解析后的数据
4.2 默认JSONParser,FormParser,MultiPartParser三个解析器类
4.3 可以在全局配置文件settings.py中修改DRF全局参数,以REST_FRAMEWORK作为名称
4.3.1 pycharm中连续按击2次shilft键,可以全局搜索文件,搜索restframework中的settings.py配置文件并进入
4.3.2 将需要的DEFAULT_XXXX_CLASSES复制粘贴至项目的全局配置文件settings.py文件中
粘贴到项目全局配置文件settings.py
5.render渲染器类
5.1 DRF中的renderx渲染器可以根据请求头中的Content-Type来自动渲染前端需要的数据
5.2 默认渲染器为JSONRenderer,FormParser,MultiPartParser三个渲染器类
5.3 如果前端请求头未指定Accept参数或者指定为Accept:application/json,那么会自动返回
json格式的数据
5.4 如果前端请求头指定Accept参数Accept:text/html,那么会自动返回可浏览的api页面
(对api进行管理)
5.5 可以在全局配置文件settings.py中修改DRF全局参数,以REST_FRAMEWORK作为名称,
在其中添加DEFAULT_RENDERER_CLASSES
5.6 pycharm中连续按击2次shilft键,可以全局搜索文件,搜索restframework中的settings.py配置文件并进入
5.7 可以在继承了APIView的类视图中单独指定渲染器,优先级>全局配置文件中的渲染器
6. 继承APIView的类视图代码:
import json
from django.http import HttpResponse, JsonResponse
# 子应用视图
from django.views import View
from rest_framework import status
from rest_framework.renderers import JSONRenderer
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.views import APIView
from projects.models import Projects
# from projects.serializers import ProjectSerializer
from projects.serializers import PorjectModelSerializer
class JsonDecoderError111(BaseException):
"""
1.serializers.ModelSerializer提供模型对象序列化+create()方法+update()方法
2。APIView 提供从request.data中获取请求参数+返回Response()对象
"""
pass
# class ProjectsView(View):
class ProjectsView(APIView):
"""
APIView类视图
:param View: 继承自from rest_framework.views import APIView
:return: Response对象
"""
# renderer_classes = [JSONRenderer]
querySet = Projects.objects.all()
serializer_class = PorjectModelSerializer
def get(self, request: Request):
# 查询所有项目信息
# GET /projects/
querySet = self.querySet
serializer = self.serializer_class(instance=querySet, many=True)
return Response(serializer.data, status=status.HTTP_200_OK)
def post(self, request: Request):
# 新建项目
# POST /projects/ json格式参数
# try:
# python_data = json.loads(request.body)
# except:
# return Response({'msg': '参数有误'}, status=400)
# python_data = request.data
serializer = self.serializer_class(data=request.data)
# 需要调用序列化器serializer的is_valid()方法才能开始校验输入数据
# if not serializer.is_valid():
# return JsonResponse({'msg': serializer.errors}, status=501)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
class ProjectDetailView(APIView):
get_pro_obj = Projects.objects.get
serializer_class = PorjectModelSerializer
def get(self, request, pk):
# 查询指定项目
# GET /projects/<int:pk>/
pro_obj = self.get_pro_obj(id=pk)
serializer = self.serializer_class(instance=pro_obj)
# pro_obj = models.Projects.objects.get(id=request.data.get(pk))
# serializer = PorjectModelSerializer(instance=pro_obj)
# return Response(serializer.data, status=status.HTTP_200_OK)
return Response(serializer.data, status=status.HTTP_200_OK)
def put(self, request: Request, pk):
# 修改项目
# PUT /projects/<int:pk>/ json格式参数
# try:
# python_data = json.loads(request.body)
# except:
# return JsonResponse({'msg': '参数有误1'}, status=400)
# python_data = request.data
# 获取待更新的对象
pro_obj = self.get_pro_obj(id=pk)
serializer = self.serializer_class(instance=pro_obj, data=request.data)
# if not serializer.is_valid():
# return JsonResponse({'msg': serializer.errors}, status=400)
serializer.is_valid(raise_exception=True)
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
def delete(self, request: Request, pk):
# 删除项目
# DELETE /projects/<int:pk>
pro_obj = self.get_pro_obj(id=pk)
status = pro_obj.delete()
result = {
'msg': f'删除{pk}成功',
'count': status,
}
return Response(data=result, status=204)