drf4-响应-请求-视图组件-
drf请求与响应
drf视图组件
drf视图基类
DRF中请求与响应
rest framework 传入视图的request对象不再是Django的默认的httpRequest对象
而是rest framework 提供的扩展了Httprequest的Request类的对象
rest framework 提供了parser解析器,接受到请求后会自动根据content-type指明的请求数据类进行解析,
解析类querydict保存到request对象中
request对象的数据是自动根据前端发送数据的格式进行解析之后的结果
1.无论前端发送那种格式的数据,我们都可以统一方式读取数据
Request 类
属性
1.request.data
data:包含解析之后的文件和非文件数据
POST,PUT,PATCH请求解析后的数据
原生django,put提交的数据在request.post中是取不到的
2.request.query_parms
跟request.get相同,只是更换更正确的名称
3.其他属性方法
其他属性,跟正常的request照常使用
Response类
rest_framework.response.Response
drf 的response构造方式
def __init__(self, data=None, status=None,
template_name=None, headers=None,
exception=False, content_type=None)
-------------------------------------------------------------------
data:None 字典,列表 序列化成json格式字符串,返回给前端(放在http响应的body)
status: None http响应的状态码,默认是200,201 (drf已经把所有状态码做成了常量,可以直接导进来100~500)
headers =None #http的响应头,字典('name':'lzl')
content_type=None 默认是json,实际是json,实际是根据对方请求的方式并返回,对方是text/html 就返回text/html
drf能够解析的请求编码,响应编码
请求编码(request)
在drf中,两套编码解析配置,一套是drf内置默认的,一套是settings.py。
默认(内置): urlencoded
form- data
json
灵活配置请求编码
1.内置
DEFAULT_PARSER_CLASSES(默认的解析类)
-'rest_framework.parsers.JSONParser', 可以解析json格式
-'rest_framework.parsers.FormParser', 可以解析urlencoded格式
-'rest_framework.parsers.MultiPartParser' 可以解析form-data格式
------------------------------------------------------------------------------
2.全局(settings.py)
REST_FRAMEWORK = {
'DEFAULT_PARSER_CLASSES': [
'rest_framework.parsers.JSONParser',
# 'rest_framework.parsers.FormParser',
# 'rest_framework.parsers.MultiPartParser',
],
}
-----------------------------------------------------------------------------------
3.局部(配置)
class TestView(APIView):
parser_classes = [JSONParser,FormParser,MultiPartParser]
请求编码配置写总结
1.解析的使用顺序,优先用视图类自己的,然后用项目配置文件,最后用内置的
2.实际项目如何配置,基本上都运行jsonParser,FormParser,如果上传文件只允许multiPartParser
响应编码(Response)
在drf中,浏览器接受返回响应的数据看到的样子是经过美化的。
在postman软件中,我们只能看到json格式、
!默认情况下,响应的编码应该是根据客户端类型决定的
灵活配置响应编码
#1.全局配置:项目的配置文件(settings,py)
-----------------------------------------------------------------------
REST_FRAMEWORK = {
'DEFAULT_RENDERER_CLASSES': [
# 'rest_framework.renderers.JSONRenderer', # json格式
'rest_framework.renderers.BrowsableAPIRenderer', #浏览器的格式
]
}
-----------------------------------------------------------------------------------------
#局部配置(代码块中)
class TestView(APIView):
renderer_classes = [JSONRenderer,]
响应编码配置总结
实际响应编码中,一般选择默认,不作配置
drf 视图组件、
Django Rest FrameWork 提供的视图的主要作用:
控制序列化器的执行(检验,转换数据)
REST framework 提供了众多的通用视图基类与扩展类,以简化视图的编写
drf两个视图基类
APIView
rest_framework.views.APIView
APIView是REST framework提供的所有视图的基类,继承自Django的View父类。
APIView与View的不同之处在于:
传入到视图方法中的是REST framework的Request对象,而不是Django的HttpRequeset对象;
视图方法可以返回REST framework的Response对象,视图会为响应数据设置(render)符合前端要求的格式;
任何APIException异常都会被捕获到,并且处理成合适的响应信息;
在进行dispatch()分发前,会对请求进行身份认证、权限检查、流量控制。
支持定义的类属性
authentication_classes 列表或元祖,身份认证类
permissoin_classes 列表或元祖,权限检查类
throttle_classes 列表或元祖,流量控制类
在APIView中仍以常规的类视图定义方法来实现get() 、post() 或者其他请求方式的方法。
---------------------------------------------------------------------------------------------------------------------------------
举例:
from rest_framework.views import APIView
from rest_framework.response import Response
# url(r'^students/$', views.StudentsAPIView.as_view()),
class StudentsAPIView(APIView):
def get(self, request):
data_list = Student.objects.all()
serializer = StudentModelSerializer(instance=data_list, many=True)
return Response(serializer.data)
GenericAPIView(通用视图类)
rest_framework.generics.GenericAPIView
继承自APIVIew,主要增加了操作序列化器和数据库查询的方法,作用是为下面Mixin扩展类的执行提供方法支持。通常在使用时,可搭配一个或多个Mixin扩展类。
提供的关于序列化器使用的属性与方法
--------------------------------------------------
属性:
serializer_class 指明视图使用的序列化器
---------------------------------------------------------
方法:
get_serializer_class(self)
当出现一个视图类中调用多个序列化器时,那么可以通过条件判断在get_serializer_class方法中通过返回不同的序列化器类名就可以让视图方法执行不同的序列化器对象了。
返回序列化器类,默认返回serializer_class,可以重写,例如:
def get_serializer_class(self):
if self.request.user.is_staff:
return FullAccountSerializer
return BasicAccountSerializer
get_serializer(self, args, *kwargs)
返回序列化器对象,主要用来提供给Mixin扩展类使用,如果我们在视图中想要获取序列化器对象,也可以直接调用此方法。
注意,该方法在提供序列化器对象的时候,会向序列化器对象的context属性补充三个数据:request、format、view,这三个数据对象可以在定义序列化器时使用。
request 当前视图的请求对象
view 当前请求的类视图对象
format 当前请求期望返回的数据格式
提供的关于数据库查询的属性与方法
---------------------------------------------------------------------------------------------------------------------------
属性:
queryset 指明使用的数据查询集
方法:
get_queryset(self)
返回视图使用的查询集,主要用来提供给Mixin扩展类使用,是列表视图与详情视图获取数据的基础,默认返回queryset属性,可以重写,例如:
def get_queryset(self):
user = self.request.user
return user.accounts.all()
get_object(self)
-----------------------------------------------------------------------------------------------------------------
返回详情视图所需的模型类数据对象,主要用来提供给Mixin扩展类使用。
在试图中可以调用该方法获取详情信息的模型类对象。
若详情访问的模型类对象不存在,会返回404。
该方法会默认使用APIView提供的check_object_permissions方法检查当前对象是否有权限被访问。
3.1 基于APIView写5个接口
class UserView(APIView):
def get(self, request):
book_list = User.objects.all()
ser = UserSerializer(instance=book_list, many=True)
return Response(ser.data)
def post(self, request):
ser = UserSerializer(data=request.data)
if ser.is_valid():
ser.save()
return Response({'code': 100, 'msg': "新增成功"}, status=201)
else:
return Response({'code': 101, 'msg': ser.errors})
class UserDetailView(APIView):
def get(self, request, pk):
book = User.objects.filter(pk=pk).first()
ser = UserSerializer(instance=book)
return Response(ser.data)
def put(self, request, pk):
book = User.objects.filter(pk=pk).first()
ser = UserSerializer(instance=book, data=request.data)
if ser.is_valid():
ser.save()
return Response({'code': 100, 'msg': "修改成功"}, status=201)
else:
return Response({'code': 101, 'msg': ser.errors})
def delete(self, request, pk):
User.objects.filter(pk=pk).delete()
return Response('')
3.2 基于GenericAPIView写5个接口
from rest_framework.generics import GenericAPIView
class UserView(GenericAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
def get(self, request):
book_list = self.get_queryset()
ser = self.get_serializer(instance=book_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': 100, 'msg': "新增成功"}, status=201)
else:
return Response({'code': 101, 'msg': ser.errors})
class UserDetailView(GenericAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
def get(self, request, pk):
book = self.get_object()
ser = self.get_serializer(instance=book)
return Response(ser.data)
def put(self, request, pk):
book = self.get_object()
ser = self.get_serializer(instance=book, data=request.data)
if ser.is_valid():
ser.save()
return Response({'code': 100, 'msg': "修改成功"}, status=201)
else:
return Response({'code': 101, 'msg': ser.errors})
def delete(self, request, pk):
self.get_queryset().filter(pk=pk).delete()
return Response('')