博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Django REST Framework提供的视图
阅读量:3960 次
发布时间:2019-05-24

本文共 8607 字,大约阅读时间需要 28 分钟。

Django REST Framework之视图

drf除了在数据序列化部分简写代码以外,还在视图中提供了简写操作。所以在django原有的django.views.View类基础上,drf封装了多个视图子类出来提供给我们使用。

Django REST framwork 提供的视图的主要作用:

  • 控制序列化器的执行(检验、保存、转换数据)
  • 控制数据库查询的执行
  • 调用请求类和响应类[这两个类也是由drf帮我们再次扩展了一些功能类。

一、基于APIView的视图方法:

1.现创建Model模型类对象:

from django.db import models# Create your models here.class Student(models.Model):    # 模型字段    name = models.CharField(max_length=100,verbose_name="姓名",help_text='提示文本:不能为空')    sex = models.BooleanField(default=1,verbose_name="性别")    age = models.IntegerField(verbose_name="年龄")    class_null = models.CharField(max_length=5,verbose_name="班级编号")    description = models.TextField(max_length=1000,verbose_name="个性签名")    class Meta:        db_table="tb_student"  #可以让数据库生成表的时候使用该名称        verbose_name = "学生"        verbose_name_plural = verbose_name

2.创建一个序列化器:

from app01 import modelsfrom rest_framework import serializersclass StudentSerializer(serializers.ModelSerializer):#会针对数据库中的所有字段进行校验    class Meta:        model = models.Student        fields = '__all__'        extra_kwargs = {
'id':{
'read_only':True}, 'age':{
'write_only':True}, }class Student2Serializer(serializers.ModelSerializer):#对指定字段进行校验 class Meta: model = models.Student fields = ['name','class_null'] extra_kwargs = {
'id':{
'read_only':True}, 'age':{
'write_only':True}, } # read_only=True,序列化时序列化出该字段数据,反序列化校验时不要校验这个数据 # write_only=True,序列化时不序列化这个字段数据,反序列校验时,需要客户端传递这个数据过来进行校验

3.先写一个基于APIView的视图:

APIViewView的不同之处在于:

  • 传入到视图方法中的是REST framework的Request对象,而不是Django的HttpRequeset对象;
  • 视图方法可以返回REST framework的Response对象,视图会为响应数据设置(render)符合前端要求的格式;
  • 任何APIException异常都会被捕获到,并且处理成合适的响应信息;
  • 在进行dispatch()分发前,会对请求进行身份认证、权限检查、流量控制。

支持定义的类属性

  • authentication_classes 列表或元祖,身份认证类
  • permissoin_classes 列表或元祖,权限检查类
  • throttle_classes 列表或元祖,流量控制类
#使用5个接口来实现一下,由于一个类里面无法完成两件相同事件,所有定义俩个类from django.shortcuts import renderfrom rest_framework.views import APIView# Create your views here.from rest_framework import statusfrom app01 import modelsfrom .serializers import StudentSerializer, Student2Serializerfrom rest_framework.response import Responseclass Students1View(APIView):    # 获取所有数据接口    def get(self,request):        all_data = models.Student.objects.all()        serializer = StudentSerializer(instance=all_data,many=True)        return Response(serializer.data)    # 添加一条记录的接口    def post(self,request):        data = request.data        serializer = StudentSerializer(data=data)        if serializer.is_valid():            instance = serializer.save()  #instance为添加的新纪录对象            serializer = StudentSerializer(instance=instance)            return Response(serializer.data,status=status.HTTP_201_CREATED)        else:            print(serializer.errors)class Student1View(APIView):    # 获取单条记录    def get(self,request,pk):        stu_obj = models.Student.objects.get(pk=pk)        serializer = StudentSerializer(instance=stu_obj)        return Response(serializer.data)    # 更新单条记录    def put(self,request,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)            return Response(serializer.data)        else:            print(serializer.errors)    # 删除单条记录    def delete(self,request,pk):        models.Student.objects.get(pk=pk).delete()        return Response(None,status=status.HTTP_204_NO_CONTENT)

4.路由:

urlpatterns = [path('students1/', views.Students1View.as_view()),re_path('students1/(?P
\d+)/', views.Student1View.as_view()),

二、基于GenericAPIView的视图方法:

1.以上其他不变在view视图中加入此代码简化上方代码

from rest_framework.generics import GenericAPIViewfrom rest_framework.mixins import ListModelMixinclass Students2View(GenericAPIView,):    queryset = models.Student.objects.all()  #必须要指定的    serializer_class = StudentSerializer  #选填的  #当出现一个视图类中调用多个序列化器时,那么可以通过条件判断在get_serializer_class方法中通过返回不同的序列化器类名就可以让视图方法执行不同的序列化器对象了,返回序列化器类,默认返回`serializer_class`,可以重写,例如:    # def get_serializer_class(self):    #     if self.request.method == 'GET':    #         return Student2Serializer    #     else:    #         return StudentSerializer    # 获取所有数据接口    def get(self, request):        # all_data = models.Student.objects.all()        # serializer = StudentSerializer(instance=all_data, many=True)        serializer = self.get_serializer(instance=self.get_queryset(), many=True)        return Response(serializer.data)    # 添加一条记录的接口    def post(self, request):        data = request.data        serializer = self.get_serializer(data=data)        if serializer.is_valid():            instance = serializer.save()  # instance为添加的新纪录对象            serializer = self.get_serializer(instance=instance)            return Response(serializer.data, status=status.HTTP_201_CREATED)        else:            print(serializer.errors)            return Response({
'error':'字段错误'})class Student2View(GenericAPIView): queryset = models.Student.objects.all() serializer_class = StudentSerializer # 获取单条记录 def get(self, request, pk): # stu_obj = models.Student.objects.get(pk=pk) serializer = self.get_serializer(instance=self.get_object()) return Response(serializer.data) # 更新单条记录 def put(self, request, pk): # stu_obj = models.Student.objects.get(pk=pk) data = request.data serializer = self.get_serializer(instance=self.get_object(), data=data, partial=True) if serializer.is_valid(): # print('>>>',serializer.data) #在save方法之前,不能调用data属性,serializer.data instance = serializer.save() # instance为添加的新纪录对象 print(serializer.data) #之后可以看 serializer = self.get_serializer(instance=instance) return Response(serializer.data) else: print(serializer.errors) # 删除单条记录 def delete(self, request, pk): models.Student.objects.get(pk=pk).delete() return Response(None, status=status.HTTP_204_NO_CONTENT)

2.路由:

urlpatterns = [path('students2/', views.Students2View.as_view()),re_path('students2/(?P
\d+)/',views.Student2View.as_view())]

三、基于GenericAPIView的五个扩展类视图方法:

(1)ListModelMixin:

获取多条数据的 列表视图扩展类,提供list(request, *args, **kwargs)方法快速实现列表视图,返回200状态码。

该Mixin的list方法会对数据进行过滤和分页。


(2)CreateModelMixin:

添加数据的创建视图扩展类,提供create(request, *args, **kwargs)方法快速实现创建资源的视图,成功返回201状态码。

如果序列化器对前端发送的数据验证失败,返回400错误。


(3)RetrieveModelMixin:

获取单条数据,详情视图扩展类,提供retrieve(request, *args, **kwargs)方法,可以快速实现返回一个存在的数据对象。

如果存在,返回200, 否则返回404。


4)UpdateModelMixin:

更新视图扩展类,提供update(request, *args, **kwargs)方法,可以快速实现更新一个存在的数据对象。

同时也提供partial_update(request, *args, **kwargs)方法,可以实现局部更新。

成功返回200,序列化器校验数据失败时,返回400错误。


(5)DestroyModelMixin:

删除视图扩展类,提供destroy(request, *args, **kwargs)方法,可以快速实现删除一个存在的数据对象。

成功返回204,不存在返回404。

from rest_framework.generics import GenericAPIViewfrom rest_framework.mixins import ListModelMixin,CreateModelMixin,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixinclass Students3View(GenericAPIView,ListModelMixin,CreateModelMixin):    queryset = models.Student.objects.all()  #必须要指定的    serializer_class = StudentSerializer  #选填的    # 获取所有数据接口    def get(self, request):        return self.list(request)    # 添加一条记录的接口    def post(self, request):        return self.create(request)class Student3View(GenericAPIView,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin):    queryset = models.Student.objects.all()    serializer_class = StudentSerializer    # 获取单条记录    def get(self, request, pk):        return self.retrieve(request, pk)    # 更新单条记录    def put(self, request, pk):        return self.update(request, pk)    # 删除单条记录    def delete(self, request, pk):        return self.destroy(request, pk)

路由:

urlpatterns = [path('students3/', views.Students3View.as_view()),re_path('students3/(?P
\d+)/',views.Student3View.as_view())]

四、基于GenericAPIView的视图子类视图方法:

1.在Views中继续简化我们的代码

from rest_framework.generics import ListAPIView,CreateAPIView,RetrieveAPIView,UpdateAPIView,DestroyAPIViewclass Students4View(ListAPIView,CreateAPIView):    queryset = models.Student.objects.all()  #必须要指定的    serializer_class = StudentSerializer  #选填的class Student4View(RetrieveAPIView,UpdateAPIView,DestroyAPIView):    queryset = models.Student.objects.all()    serializer_class = StudentSerializer

2.路由

urlpatterns = [path('students4/', views.Students4View.as_view()),re_path('students4/(?P
\d+)/',views.Student4View.as_view())]

至此我们的代码就简化完毕了,建议还是多看看源码会对自己有很大帮助的。

转载地址:http://dgqzi.baihongyu.com/

你可能感兴趣的文章
网络路由
查看>>
网络 tcp 性能 可靠
查看>>
网络 https 握手
查看>>
去掉调试信息
查看>>
lsof 使用
查看>>
golang获取本机地址
查看>>
date 使用
查看>>
ipcalc
查看>>
网络 linux 禁止 ping
查看>>
ELF 格式详解
查看>>
chromium 使用
查看>>
linux 检测虚拟机类型
查看>>
go - 运行时:内存不足
查看>>
top 使用
查看>>
Linux Netlink通信机制详解
查看>>
rsync 远程同步
查看>>
nano使用
查看>>
c函数
查看>>
linux 链接
查看>>
centos6.x 添加开机启动服务
查看>>