drf请求和响应、2基类、5个视图扩展类、9个视图子类
1、
视图类继承APIView后多了 -0 去除了csrf认证 -1 新的request -request.data -request.query_params -request.其他跟之前一样 -request._request 是老的 -2 三大认证 -3 全局异常
JSONParser: 解析json格式
FormParser: 默认的编码 urlencoded
MultiPartParser: 传文件格式 form-data
from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.parsers import JSONParser, FormParser, MultiPartParser from rest_framework.renderers import JSONRenderer, BrowsableAPIRenderer
局部限制
写一个类属性 parser_classes = [JSONParser或者FormParser、MultiPartParser]
class BookView(APIView):
# 类属性
parser_classes = [JSONParser]
def get(self, request):
res = Response(data={123}, status=500, headers={'xxx': 'yyy'})
print(res.data)
return res
def post(self, request):
print(self.parser_classes)
print(request.data)
return Response('新增')
效果:

全局限制
REST_FRAMEWORK = {
#####请求体的限制
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
'rest_framework.parsers.FormParser',
# 'rest_framework.parsers.MultiPartParser'
],
#####响应格式的限制
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
],
}
补充:
全局使用后,局部再限制---》只需要在视图类上加即可
全局如果用了,局部这样配,优先用局部的,也就是这个类管理的接口,只能接收form-data格式 parser_classes = [MultiPartParser]
二、
1、
# from rest_framework.response import Response
### __init__ 中需要传这几个参数,不传也可以
data=None # 字典,列表,字符串,空赋值给它---》http响应体中 ---》第一个参数是它
status=None, # http响应状态码,默认是200,千万不能写成1xx
headers=None, # http响应头,后期我们可以往响应头中放数据
content_type=None # 响应编码格式(不用管,用浏览器访问就是:text/html,用postman就是:json格式)
template_name=None # 模版名字 默认是:rest_framework/api.html 了解,可以定制自己返回的页面样子
###补充:后面会用---》通过res.data 就能取到当时放的datga
res=Response(data={},status=500,headers={'xxx':'yyy'})
print(res.data)
return res
### 补充:取当时放的响应头
res.headers 拿不到数据,可以通过下面的方式或得到
print(res['xxx'])
print(res.has_header('zzz'))
serializer 类中序列化后的字段,通过 Response(ser.data)第一个参数赋值给data
publish_detail = serializers.DictField(read_only=True) author_list = serializers.ListField(read_only=True)
2、
响应有编码格式:默认支持json和text/html(浏览器)
# 修改只支持json
### 局部使用
class BookView(APIView):
renderer_classes = [BrowsableAPIRenderer]
### 全局使用
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
'rest_framework.renderers.JSONRenderer',
'rest_framework.renderers.BrowsableAPIRenderer',
],
}
##局部禁用---》全局已经配置了---》局部想用浏览器的样子
class BookView(APIView):
renderer_classes = [BrowsableAPIRenderer]
# 如果不配置---》有默认
-解析:三种编码都能解析
-响应:浏览器访问看到浏览器的样子,postman访问,看到json格式
3、基于原生的django,向响应头写入数据
from django.http import HttpResponse
def custom_header_view(request):
# 创建一个HttpResponse对象
response = HttpResponse("Hello, World!")
# 向响应头添加自定义信息
response['X-Custom-Header'] = 'this is a test'
return response

三、两个基类APIView和GenericAPIView
基于 GenericAPIView 写接口
1、GenericAPIView 源码内容
# GenericAPIView 有类属性和方法
### 重要属性###
-queryset:以后放所有某个表查询出的数据
-serializer_class:要序列化的类
### 重要方法###
-get_queryset :要序列化的所有数据,qs对象
-get_serializer :序列化类
-get_object :修改,查询的单条
## 了解类属性:
-lookup_field = 'pk' 路由使用转换器,转换出来的参数,查询单条要用到,如果改了,路由对应也要修改,一般不改
-filter_backends:后面详细讲 过滤 功能
-pagination_class :后面详细讲 分页
### 了解方法
-get_serializer_class 后期咱们可能会重写它,指定某些方法使用不同的序列化类
-filter_queryset 后面跟过滤功能一起讲
补充:手写GenericAPIView
两个类属性,三个方法
class GenericAPIView(APIView):
queryset = None
serializer_class = None
def get_queryset(self):
return self.queryset.all() # 真正使用的时候,再加all获取所有才行
def get_serializer(self, *args, **kwargs):
return self.serializer_class(*args, **kwargs)
def get_object(self, pk):
res = self.get_queryset()
return res.filter(pk=pk).first()
2、案例代码
view
class PublishView(GenericAPIView):
# 定义两个类属性,方便用的时候进行替换
queryset = Publish.objects.all()
serializer_class = PublishSerializer
def get(self, request):
obj_list = self.get_queryset()
ser = self.get_serializer(instance=obj_list, many=True)
return Response(ser.data)
def post(self, request):
ser = self.get_serializer(data=request.data)
if ser.is_valid():
ser.save()
return Response({'code': 200, "data": ser.data, 'msg': "添加成功"})
else:
return Response(ser.errors)
class PublishDetailView(GenericAPIView):
queryset = Publish.objects.all() # 表数据查询结果
serializer_class = PublishSerializer # 序列化实例
def get(self, request, pk):
obj = self.get_object()
ser = self.get_serializer(instance=obj)
return Response(ser.data)
def put(self, request, pk):
obj = self.get_object()
ser = self.get_serializer(instance=obj, data=request.data)
if ser.is_valid():
ser.save()
return Response({'code': 200, "data": ser.data, 'msg': "修改成功"})
return Response(ser.errors)
def delete(self, request, pk):
self.get_object().delete()
return Response('删除成功!')
注意:
-get_object方法 :修改,查询单条、删除使用
serializer
class PublishSerializer(serializers.ModelSerializer):
class Meta:
model = Publish
# fields = '__all__'
fields = ['name', 'addr']
四、五
ListModelMixin :查询所有记录
CreateModelMixin:新增记录
UpdateModelMixin:修改某一条记录
DestroyModelMixin:删除某一条记录
RetrieveModelMixin:查询一条记录
1、view
from rest_framework.mixins import ListModelMixin, CreateModelMixin, UpdateModelMixin, DestroyModelMixin, \
RetrieveModelMixin
class PublishView(GenericAPIView, ListModelMixin, CreateModelMixin):
queryset = Publish.objects.all()
serializer_class = PublishSerializer
def get(self, request):
return self.list(request)
def post(self, request):
return self.create(request)
class PublishDetailView(GenericAPIView, RetrieveModelMixin, UpdateModelMixin, DestroyModelMixin):
queryset = Publish.objects.all()
serializer_class = PublishSerializer
def put(self, request, pk):
return self.update(request, pk)
def get(self, request, pk):
return self.retrieve(request, pk)
def delete(self, request, pk):
return self.destroy(request, pk)
补充:ListModelMixin 扩展类的源码,里面用到了GenericeAPIView的get_queryset()、get_serializer() 两个方法。
在视图类中 return self.list(request) 就是利用ListModelMixin 扩展类做了序列化和反序列化操作、resturn Response(serizlizer.data)
def list(self, request, *args, **kwargs):
queryset = self.filter_queryset(self.get_queryset())
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
2、serializer
class PublishSerializer(serializers.ModelSerializer):
class Meta:
model = Publish
# fields = '__all__'
fields = ['name', 'addr']
五、九个视图子类
1、九个视图子类分类
不带pk的
ListAPIView, CreateAPIView, ListCreateAPIView
带pk的
RetrieveAPIView, UpdateAPIView, DestroyAPIView
RetrieveUpdateDestroyAPIView, RetrieveDestroyAPIView, RetrieveUpdateAPIView
2、有了这九个视图子类可以大大减少代码量
导入:九个视图子类有继承 GenericAPIView,它们都可以从.generics 里导入
from rest_framework.generics import ListCreateAPIView
class PublishView(ListAPIView, ListCreateAPIView, CreateAPIView):
queryset = Publish.objects.all()
serializer_class = PublishSerializer
class PublishDetailView(RetrieveUpdateDestroyAPIView):
queryset = Publish.objects.all()
serializer_class = PublishSerializer
注:
以后想写5个接口中的某一个或某几个或所有,只需要选择继承不同的类即可,类中只需要配置两个类属性
没有继承的类相应的接口就没法使用

3、路由和序列化文件不变和之前写法一致
###路由
from django.urls import path
from app01.views import PublishView, PublishDetailView
urlpatterns = [
path('publishs/', PublishView.as_view()),
path('publishs/<int:pk>', PublishDetailView.as_view()),
]
###序列化文件
class PublishSerializer(serializers.ModelSerializer):
class Meta:
model = Publish
# fields = '__all__'
fields = ['name', 'addr']

浙公网安备 33010602011771号