本文共 8607 字,大约阅读时间需要 28 分钟。
drf除了在数据序列化部分简写代码以外,还在视图中提供了简写操作。所以在django原有的django.views.View类基础上,drf封装了多个视图子类出来提供给我们使用。
Django REST framwork 提供的视图的主要作用:
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的视图:
APIView
与View
的不同之处在于:
Request
对象,而不是Django的HttpRequeset
对象;Response
对象,视图会为响应数据设置(render)符合前端要求的格式;APIException
异常都会被捕获到,并且处理成合适的响应信息;支持定义的类属性
#使用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()),
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())]
(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())]
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/