1.Request和Response类
- Request:framework传入视图的request对象不再是Django默认的HttpRequest对象,卫视farmework提供的扩展了HttpRequest类的对象。
Request独享的数据是自动根据前端发送数据的格式进行解析之后的结果.常用属性:
(1).data: request.data返回解析之后的请求体数据。 类似于Django中标准的request.POST和request.FILES属性,但提供如下特性: (1)包含了解析之后的文件盒非文件数据; (2)包含了对POST,PUT,PATCH(修改的请求方式)请求方式解析后的数据; (3)利用了REST farmework的parsers解析器,不仅支持表单类型数据,也支持JSON数据。(2)query_params: request.query_params与Django标准的request.GET相同,只是更换了更正确的名称而已。 底层原理__getattr__
- Response:farmework提供了一个响应类Response,使用该类构造响应对象时,相应的具体数据内容会被转换成符合前端需求的类型。
构造方法:Response(data, status=None, template_name=None, headers=None, content_type=None) (1)data=None:字典,列表序列化成json格式字符串,返回给前端(这时数据放在http响应的body中) (2)status=None:http相应的状态码,默认是200,201;drf默认帮所有的http响应状态码都做成了常量,可以直接导进去使用。 (3)headers=None:http的响应头,字典{name:lqz} -原生django要在响应头中加数据: res=JsonResponse(d) res['rrr']='yyy' return res (4)template_name=None:在浏览器中看到好看的页面,指定的模板; (5)content_type=None:响应的编码格式(json)
- 为了方便设置状态码,REST framewrok在rest_framework.status模块中提供了常用状态码常量。
(1)信息告知 - 1xx HTTP_100_CONTINUE HTTP_101_SWITCHING_PROTOCOLS (2)成功 - 2xx HTTP_200_OK HTTP_201_CREATED HTTP_202_ACCEPTED HTTP_203_NON_AUTHORITATIVE_INFORMATION HTTP_204_NO_CONTENT HTTP_205_RESET_CONTENT HTTP_206_PARTIAL_CONTENT HTTP_207_MULTI_STATUS (3)重定向 - 3xx HTTP_300_MULTIPLE_CHOICES HTTP_301_MOVED_PERMANENTLY HTTP_302_FOUND HTTP_303_SEE_OTHER HTTP_304_NOT_MODIFIED HTTP_305_USE_PROXY HTTP_306_RESERVED HTTP_307_TEMPORARY_REDIRECT (4)客户端错误 - 4xx HTTP_400_BAD_REQUEST HTTP_401_UNAUTHORIZED HTTP_402_PAYMENT_REQUIRED HTTP_403_FORBIDDEN HTTP_404_NOT_FOUND HTTP_405_METHOD_NOT_ALLOWED HTTP_406_NOT_ACCEPTABLE HTTP_407_PROXY_AUTHENTICATION_REQUIRED HTTP_408_REQUEST_TIMEOUT HTTP_409_CONFLICT HTTP_410_GONE HTTP_411_LENGTH_REQUIRED HTTP_412_PRECONDITION_FAILED HTTP_413_REQUEST_ENTITY_TOO_LARGE HTTP_414_REQUEST_URI_TOO_LONG HTTP_415_UNSUPPORTED_MEDIA_TYPE HTTP_416_REQUESTED_RANGE_NOT_SATISFIABLE HTTP_417_EXPECTATION_FAILED HTTP_422_UNPROCESSABLE_ENTITY HTTP_423_LOCKED HTTP_424_FAILED_DEPENDENCY HTTP_428_PRECONDITION_REQUIRED HTTP_429_TOO_MANY_REQUESTS HTTP_431_REQUEST_HEADER_FIELDS_TOO_LARGE HTTP_451_UNAVAILABLE_FOR_LEGAL_REASONS (5)服务器错误 - 5xx HTTP_500_INTERNAL_SERVER_ERROR HTTP_501_NOT_IMPLEMENTED HTTP_502_BAD_GATEWAY HTTP_503_SERVICE_UNAVAILABLE HTTP_504_GATEWAY_TIMEOUT HTTP_505_HTTP_VERSION_NOT_SUPPORTED HTTP_507_INSUFFICIENT_STORAGE HTTP_511_NETWORK_AUTHENTICATION_REQUIRED
2.drf能够解析的请求编码
- 默认能解析的请求编码:
urllencoded
form-data
json- 请求编码主要通过配置来完成:
(1)drf中有两套配置,一套是项目中的配置(settings.py),一套是默认配置;
(2)drf的配置文件settings.py中有DEFAULT_PARSER_CLASSES(默认的解析类)'rest_framework.parsers.JSONParser', 可以解析json格式 'rest_framework.parsers.FormParser', 可以解析urlencoded格式 'rest_framework.parsers.MultiPartParser' 可以解析form-data格式
- 这边来个需求实际展示一下配置
需求:想让我们的接口只能接收json格式: 方式一:全局配置,则在drf的项目配置文件中修改(对于不需要的格式注释掉即可) REST_FRAMEWORK = { 'DEFAULT_PARSER_CLASSES': [ 'rest_framework.parsers.JSONParser', # 'rest_framework.parsers.FormParser', # 'rest_framework.parsers.MultiPartParser', ], } 方式二:局部配置(在类中直接进行配置) class TestView(APIVew): parser_classes =[JSONParser]
- 解析类的使用顺序:
优先使用类本身的解析,然后使用项目配置文件里的,最后用内置的- 实际项目请求解析配置:
基本上都运行JSONParser,FormParser
如果上传文件只允许MultiPartParser
3.drf能够解析的响应编码
- 如果用浏览器的话会自行出现很好看的页面效果,如果用postman看到的是json格式;
默认情况下,相应的编码都是根据客户端类型决定的。- 两种配置方发:
方式一:全局配置,在项目的配置文件: REST_FRAMEWORK = { 'DEFAULT_RENDERER_CLASSES': [ 'rest_framework.renderers.JSONRenderer', # json格式 'rest_framework.renderers.BrowsableAPIRenderer', #浏览器的格式 ] } 方式二:局部配置(同样可以选择配置) class TestView(APIView): renderer_classes = [JSONRenderer,BrowsableAPIRenderer]
1.Django REST framwork 提供的视图的主要作用:
- 控制序列化器的执行(检验、保存、转换数据)
- 控制数据库查询的执行
2.视图继承关系
REST framework 提供了众多的通用视图基类与扩展类,以简化视图的编写。
1.2个视图基类
- APIView
rest_framework.views.APIView(1)APIView是REST framework提供的所有视图的基类,继承自Django的View父类。
(2)APIView与View的不同:
传入到视图的方法中的是REST framwork的Request对象,而不是Django中的HttpRequest对象;
视图方法可以返回REST framework的Response对象,视图会为响应数据设置(render)符合前端要求的格式;
任何APIException异常都会被捕获到,并且处理成合适的响应信息;
在进行dispatch()分发前,会对请求进行身份认证、权限检查、频率控制。
- GenericAPIView–>继承了APIView
rest_framework.generics.GenericAPIView(1)继承自APIVIew,主要增加了操作序列化器和数据库查询的方法,作用是为下面Mixin扩展类的执行提供方法支持。通常在使用时,可搭配一个或多个Mixin扩展类。
(2)提供的关于序列化器使用的属性与方法属性:serializer_class 指明视图使用的序列化器 例如:serializer_class = UserSerializer 方法:get_serializer(self, args, *kwargs) 获取要使用的序列化类(3)提供的关于数据库查询的属性与方法
属性:queryset 指明使用的数据查询集 例如:queryset = User.objects.all() 方法:get_queryset(self) 获取所有要序列化数据 返回视图使用的查询集,是列表视图与详情视图获取数据的基础,默认返回queryset属性, 例如: def get_queryset(self): user = self.request.user return user.accounts.all() get_object(self) 根据pk获取单个数据 返回详情视图所需的模型类数据对象,返回详情视图所需的模型类数据对象。
2.基于APIView写5个接口
class UserView(APIView): def get(self,request): book_list = User.object.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 UserDatailView(APIView): def get(self,request,pk): book = User.object.filter(pk=pk).first() ser = UserSerializer(instance=book) return Response(ser.data) def put(self,request,pk): book = User.object.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.object.filter(pk=pk).delete() return Response('')
3.基于GenericAPIView写5个接口
from rest_framework.generics import GenericAPIView class UserView(GenericAPIView): queryset = User.object.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.object.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('')
必须配合GenericAPIView使用,不能配合APIVew使用。from rest_framework.mixins import RetrieveModelMixin, CreateModelMixin, UpdateModelMixin, DestroyModelMixin, ListModelMixin1.基于GenericAPIView+5个视图扩展类写接口
作用:
提供了几种后端视图(对数据资源进行增删改查)处理流程的实现,如果需要编写的视图属于这五种,则视图可以通过继承相应的扩展类来复用代码,减少自己编写的代码量。
这五个扩展类需要搭配GenericAPIView父类,因为五个扩展类的实现需要调用GenericAPIView提供的序列化器与数据库查询的方法。
列举:
(1)ListModelMixin(list方法,就是原来咱们的get):
列表视图扩展类,提供list(request, *args, **kwargs)方法快速实现列表视图,返回200状态码。
该Mixin的list方法会对数据进行过滤盒分页。(2)CreateModelMixin(写了一个Create方法,就是原来咱们post中的代码):
创建视图扩展类,提供create(request, *args, **kwargs)方法快速实现创建资源的视图,成功返回201状态码。
如果序列化器对前端发送的数据验证失败,返回400错误。(3)RetrieveModelMixin(retrieve,就是咱们原来的get):
详情视图扩展类,提供retrieve(request, *args, **kwargs)方法,可以快速实现返回一个存在的数据对象。
如果存在,返回200,否则返回404.(4)UpdateModelMixin(update方法,就是咱们原来的put):
更新视图扩展类,提供update(request, *args, **kwargs)方法,可以快速实现更新一个存在的数据对象。
同时也提供partial_update(request, *args, **kwargs)方法,可以实现局部更新。
成功返回200,序列化器校验数据失败时,返回400错误。(5)DestoryModelMixin(destroy方法,就是原来咱们的delete):
删除视图扩展类,提供destroy(request, *args, **kwargs)方法,可以快速实现删除一个存在的数据对象。
成功返回204,不存在返回404.
代码列举:class UserView(GenericAPIView,ListModeLMixin,CreateModelMixin): # 配置两个类属性 queryset = User.object.all() serializer_class = UserSerializer def get(self,request,*args,**kwargs): return self.list(request,*args,**kwargs) def post(self,request,*args,**kwargs): return self.create(request,*args,**kwargs) class UserDetailView(GenericAPIView,RetrieveModelMiXin,UpdataModelMixin,DestoryModelMixin): queryset = User.objects.all() serializer_class = UserSerializer def get(self,request,*args,**kwargs): return self.update(request,*args,**kwargs) def put(self,request,*args,**kwargs): return srlf.update(request,*args,**kwargs) def delete(self,request,*args,**kwargs): return self.destory(request,*args,**kwargs)
视图类:继承GenericAPIView+某个或某几个视图扩展类from rest_framework.generics import ListAPIView,CreateAPIView, RetrieveAPIView,DestroyAPIView,UpdateAPIView from rest_framework.generics import ListCreateAPIView, RetrieveUpdateDestroyAPIView,RetrieveUpdateAPIView,RetrieveDestroyAPIView
列举一些:
(1)CreateAPIView
提供post方法
继承自GenericAPIView,CreateModelMinxin
(2)ListAPIView
提供get方法
继承自GenericAPIView,ListModelMixin
(3)RetrieveAPIView
提供get方法
继承自GenericAPIView,RetrieveModelMixin
(4)DestoryAPIView
提供delete方法
继承自GenericAPIView、DestoryModelMixin
(5)UpdateAPIView
提供get和patch方法
继承自:GenericAPIView、UpdateModelMixin
(6)RetrieveUpdateAPIView
提供 get、put、patch方法
继承自: GenericAPIView、RetrieveModelMixin、UpdateModelMixin
(7)RetrieveUpdateDestoryAPIView
提供 get、put、patch、delete方法
继承自:GenericAPIView、RetrieveModelMixin、UpdateModelMixin、DestoryModelMixin
举几个栗子:class UserView(ListCreateAPIView): # 配置两个 类属性 queryset = User.objects.all() serializer_class = UserSerializer class UserDetailView(RetrieveUpdateDestroyAPIView): queryset = User.objects.all() serializer_class = UserSerializer
1.使用视图集ViewSet,可以将一系列逻辑相关的动作放到一个类中:
list() 提供一组数据
retrieve() 提供单个数据
create() 创建数据
update() 保存数据
destory() 删除数据
ViewSet视图集类不再实现get()、post()等方法,而是实现动作 action 如 list() 、create() 等。视图集只在使用as_view()方法的时候,才会将action动作与具体请求方式对应上。
2.常用视图集父类
1) ViewSet
继承自APIView与ViewSetMixin,作用也与APIView基本类似,提供了身份认证、权限校验、流量管理等。ViewSet主要通过继承ViewSetMixin来实现在调用as_view()时传入字典(如{‘get’:’list’})的映射处理工作。
在ViewSet中,没有提供任何动作action方法,需要我们自己实现action方法。
2)GenericViewSet
使用ViewSet通常并不方便,因为list、retrieve、create、update、destory等方法都需要自己编写,而这些方法与前面讲过的Mixin扩展类提供的方法同名,所以我们可以通过继承Mixin扩展类来复用这些方法而无需自己编写。但是Mixin扩展类依赖与GenericAPIView,所以还需要继承GenericAPIView。GenericViewSet就帮助我们完成了这样的继承工作,继承自GenericAPIView与ViewSetMixin,在实现了调用as_view()时传入字典(如{‘get’:‘list’})的映射处理工作的同时,还提供了GenericAPIView提供的基础方法,可以直接搭配Mixin扩展类使用。
3)ModelViewSet
继承自GenericViewSet,同时包括了ListModelMixin、RetrieveModelMixin、CreateModelMixin、UpdateModelMixin、DestoryModelMixin。4)ReadOnlyModelViewSet
继承自GenericViewSet,同时包括了ListModelMixin、RetrieveModelMixin。
#两个基类 APIView GenericAPIView:有关数据库操作,queryset 和serializer_class #5个视图扩展类(rest_framework.mixins) CreateModelMixin:create方法创建一条 DestroyModelMixin:destory方法删除一条 ListModelMixin:list方法获取所有 RetrieveModelMixin:retrieve获取一条 UpdateModelMixin:update修改一条 #9个子类视图(rest_framework.generics) CreateAPIView:继承CreateModelMixin,GenericAPIView,有post方法,新增数据 DestroyAPIView:继承DestroyModelMixin,GenericAPIView,有delete方法,删除数据 ListAPIView:继承ListModelMixin,GenericAPIView,有get方法获取所有 UpdateAPIView:继承UpdateModelMixin,GenericAPIView,有put和patch方法,修改数据 RetrieveAPIView:继承RetrieveModelMixin,GenericAPIView,有get方法,获取一条 ListCreateAPIView:继承>ListModelMixin,CreateModelMixin,GenericAPIView,有get获取所有,post方法新增 RetrieveDestroyAPIView:继承RetrieveModelMixin,DestroyModelMixin,GenericAPIView,有get方法获取一条,delete方法删除 RetrieveUpdateAPIView:继承RetrieveModelMixin,UpdateModelMixin,GenericAPIView,有get获取一条,put,patch修改 RetrieveUpdateDestroyAPIView:继承RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin,GenericAPIView,有get获取一条,put,patch修改,delete删除 #视图集 ViewSetMixin:重写了as_view ViewSet: 继承ViewSetMixin和APIView GenericViewSet:继承ViewSetMixin, generics.GenericAPIView ModelViewSet:继承>mixins.CreateModelMixin,mixins.RetrieveModelMixin,mixins.UpdateModelMixin,mixins.DestroyModelMixin,mixins.ListModelMixin,GenericViewSet ReadOnlyModelViewSet:继承>mixins.RetrieveModelMixin,mixins.ListModelMixin,GenericViewSet