day73:drf:drf视图相关类&路由Routers&创建虚拟环境
目录1.APIView 2.GenericAPIView:通用视图类 3.5个视图扩展类:ListModelMixin,CreateModelMixin,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin 4.GenericAPIView的视图子类:ListAPIView,CreateAPIView,RetrieveAPIView,UpdateAPIView,DestroyAPIView 5.视图集基类:ViewSet,GenericViewSet,ModelViewSet,ReadOnlyViewSet 1.ViewSet 2.ViewSet+????APIView 3.GenericViewSet+???Mixin 4.ModelViewSet 5.ReadOnlyViewset 6.路由:Routers 1.如何添加路由数据 2.在视图集中附加action声明 3.DefaultRouter和SimpleRouter的区别(了解) 7.创建虚拟环境 附:APIView思维导图 附:drf的执行流程图 APIViewAPIView总结1.APIView中封装了自己的request和response 2.django:request.GET对应drf中的request.query_params 3.django:request.POST对应drf中的request.data 4.APIView中的response不需要写参数safe=False,ensure_ascii这些东西了,因为这些功能已经封装在response里面了 5.当我们在浏览器上访问一个url,给你回复的是一个界面。如果我们用postman访问url,给你返回的就是json数据。这是因为response中有相关配置导致的。 APIView实现代码class Students1View(APIView): # 获取所有数据接口 def get(self,request): all_data = models.Student.objects.all() 获取数据库中Student表中所有数据 serializer = StudentSerializer(instance=all_data,many=True) 将后端数据序列化 return Response(serializer.data) 将序列化之后的数据传递给前端 添加一条记录的接口 post(self,request): data = request.data 获取用户在前端输入的数据 serializer = StudentSerializer(data=data) 将数据反序列化 if serializer.is_valid(): 校验 instance = serializer.save() instance为添加的新纪录对象 serializer = StudentSerializer(instance=instance) 根据API规范,数据保存之后应该显示到前端上,所以需要将新添加的数据序列化 return Response(serializer.data,status=status.HTTP_201_CREATED) else: print(serializer.errors) Student1View(APIView): 获取单条记录 pk) serializer = StudentSerializer(instance=stu_obj) return Response(serializer.data) 更新单条记录 put(self,pk): stu_obj = models.Student.objects.get(pk=pk) data = request.data serializer = StudentSerializer(instance=stu_obj,data=data,partial=True) if serializer.is_valid(): instance = serializer.save() instance为添加的新纪录对象 serializer = StudentSerializer(instance=instance) Response(serializer.data) (serializer.errors) 删除单条记录 delete(self,pk): models.Student.objects.get(pk=pk).delete() return Response(None,status=status.HTTP_204_NO_CONTENT) GenericAPIView:通用视图类GenerivAPIView继承自APIView方法, from rest_framework.generics import GenericAPIView Students2View(GenericAPIView,): queryset = models.Student.objects.all() 指明要使用的数据查询集[必须指定] serializer_class = StudentSerializer 指明视图要使用的序列化器[可写可不写] 通过get_serializer_class来控制不同条件下,使用不同的序列化器类 get_serializer_class(self): if self.request.method == 'GET' Student2Serializer StudentSerializer all_data = models.Student.objects.all() serializer = StudentSerializer(instance=all_data,many=True) serializer = self.get_serializer(instance=self.get_queryset(),many= request.data serializer = self.get_serializer(data=data) instance为添加的新纪录对象 serializer = self.get_serializer(instance=instance) (serializer.errors) return Response({error':字段错误}) Student2View(GenericAPIView): queryset = models.Student.objects.all() serializer_class = stu_obj = models.Student.objects.get(pk=pk) serializer = self.get_serializer(instance=self.get_object()) stu_obj = models.Student.objects.get(pk=pk) data = request.data serializer = self.get_serializer(instance=self.get_object(),1)"> serializer.is_valid(): print('>>>',serializer.data) #在save方法之前,不能调用data属性,serializer.data instance = serializer.save() instance为添加的新纪录对象 print(serializer.data) 之后可以看 serializer = self.get_serializer(instance= 删除单条记录 GenericAPIView中的属性和方法
?
在视图中可以调用该方法获取详情信息的模型类对象。
返回序列化器类,默认返回 5个视图扩展类:????ModelMixin
这五个扩展类需要搭配GenericAPIView父类,因为五个扩展类的实现需要调用GenericAPIView提供的序列化器与数据库查询的方法。 换句话说。就是你在视图中的get post put等这些方法中不用写里面的代码了,里面的代码相关的操作已经被封装到对应的Mixin中了。 Students3View(GenericAPIView,ListModelMixin,CreateModelMixin): queryset = models.Student.objects.all() serializer_class = StudentSerializer self.list(request) self.create(request) Student3View(GenericAPIView,DestroyModelMixin): queryset = self.retrieve(request,pk) self.update(request,1)">return self.destroy(request,pk) GenericAPIView的视图子类:????APIView上面的代码还是过于麻烦,因为既要继承GenericAPIView又要继承Mixin系列的类。 所以将各自的操作封装成自己的APIView类。用哪个继承哪个。 而且连函数都不用写了,在???APIView类中已经有了,所以不用再写了,继承自己的APIView类即可。 ListAPIView,DestroyAPIView Students4View(ListAPIView,CreateAPIView): queryset = models.Student.objects.all() serializer_class = StudentSerializer Student4View(RetrieveAPIView,DestroyAPIView): queryset = models.Student.objects.all() serializer_class = StudentSerializer 视图集基类:ViewSet,ReadOnlyViewSetViewSet主要解决问题:之前我们在写视图类的时候,获取多条数据和提交数据放在了一个类中。获取单条数据,更新单条数据,删除多条数据放到了一个类中 这是因为多条数据操作时不需要指定pk值,而针对单条数据时,需要指定pk值。也就是说需要知道你要操作哪一条数据 这样我们就很矛盾。我们没法将5个方法放到同一个类中。 而下面的ViewSet就可以解决这个问题,将5个方法放到同一个类中 from rest_framework.viewsets ViewSet Students5View(ViewSet): def get_all_student(self,request): action all_data = models.Student.objects.all() serializer = StudentSerializer(instance=all_data,1)"> add_student(self,1)"> request.data serializer = StudentSerializer(data=instance为添加的新纪录对象 serializer = StudentSerializer(instance= get_one(self,1)">return Response(serializer.data) 通过上面代码我们可以看出。单条数据操作和多条数据被放到了一个类中。并且方法名也不再局限于必须要使用get post put...这些方法名了。 这是因为在urls.py中的as_view方法做了一个请求方法和对应函数名的指定。 而获取单条数据和获取多条数据能够共存在一个类中,是因为他们处于两个url中。虽然都是get请求过去的,但是他们在不同的url中,会执行各自的视图方法 通过下面url,我们就可以发挥出ViewSet的用处了: path(students5/',views.Students5View.as_view({getget_all_studentpostadd_student})),re_path(students5/(?P<pk>d+)/get_one'})), ViewSet+????APIView用我们刚才学的ViewSet和之前的???APIView做一个结合~ 效果:即放到了一个类中,而且各个方法里不用写详细代码(????APIView的作用) """发挥下ViewSet的作用""" ViewSet Student2ViewSet(ViewSet,ListAPIView,RetrieveAPIView): queryset = Student.objects.all() serializer_class = StudentModelSerializer GenericViewSet+???Mixin效果和Viewset+???APIView是相同的 GenericViewSet from rest_framework.mixins ListModelMixin,RetrieveModelMixin Student3ViewSet(GenericViewSet,RetrieveModelMixin): queryset = StudentModelSerializer return self.retrieve(request) 现在我们的代码是这个样子的。美中不足是我们还需要自己写def方法,其实我们希望的是类里面没有def方法的 其实。这个需求刚才在前面已经提到了。 只需要在urls.py中将get post put这类请求类型直接与Mixin中内置的list,create,update等动作方法关联起来。 这样它就会自动去执行里面的list,update方法。不需要你在视图里定义一个函数名称然后再return self.create()了。 urls.py如下所示: urlpatterns = [ path("students7/",views.Student4ViewSet.as_view({": listcreate"students7/(?P<pk>d+)/retrieveput":updatedeletedestroy{请求类型:action动作名},这样我们在视图那一块的代码又可以缩减了。函数全部无需定义了。
action methods 设置当前方法允许哪些http请求访问当前视图方法 detail 设置当前视图方法是否是操作一个数据''' detail为True,表示路径名格式应该为 router_stu/{pk}/login/ @action(methods=['],detail=True) login(self,pk): 登录""" ... detail为False 表示路径名格式应该为 router_stu/get_new_5/ @action(methods=[False) 获取最新添加的5个学生信息 ... DefaultRouter和SimpleRouter的区别(了解)
创建虚拟环境1.安装虚拟环境1.管理员方式打开终端 2.安装虚拟环境 pip install virtualenv -i https://pypi.douban.com/simple 3.终端关闭,再重新打开 4.注意:创建[环境名称]文件夹,放置所有的环境,进入指定目录 D:/envs 5.创建虚拟环境 virtualenv 环境名称 C:pythonpython3.6.exe' 这样写的前提是你的电脑已经将python加入到环境变量中''' virtualenv 环境名称 --python=python3.6 2.激活虚拟环境1.进入到虚拟环境文件夹下的Scripts目录 activate 激活虚拟环境''' 2.退出虚拟环境 deactivate 退出虚拟环境''' 3.在虚拟环境中安装模块1.激活虚拟环境 2.在激活的虚拟环境中安装模块 pip3 install django==2.2 -i http://pypi.douban.com/simple --trusted-host pypi.douban.com 3.搭建项目环境,在pycharm选择解释器时,选择你之前已经创建好的虚拟环境 4.在pycharm上使用虚拟环境附:APIView思维导图附:drf的执行流程图? (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |