DRF除了在数据序列化部分简写了代码,还在视图提供了简写操作,在doango.views.View类基础上,封装了多个视图子类,提供我们使用。
DRF提供的视图主要作用:
DRF提供了众多的通用视图基类与扩展类,以简化视图的编写。
REST framework提供了一个APIView类(基本视图类),它继承于Django的View类。
APIView类与不同的View类有所不同:
像往常一样,使用 APIView 类与使用常规 View 类非常相似,传入的请求被分派到适当的处理方法,如 .get() 或.post()。此外还新增了类属性
API 策略属性(policy attributes)
#1.models.py
class Student(models.Model):
name = models.CharField(max_length=100, verbose_name='姓名')
sex = models.BooleanField(default=1, verbose_name='性别')
classmate = models.CharField(max_length=20, verbose_name='班级')
desc = models.TextField(verbose_name='个性签名')
def __str__(self):
return self.name
#2.serializer.py
from rest_framework import serializers
from . import models
class StuModelSer(serializers.ModelSerializer):
class Meta:
model = models.Student
fields = "__all__"
#3.views.py
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from . import models
from .serializer import StuModelSer
class StuApiView(APIView):
"""获取所有数据和修改数据 的接口"""
def get(self, request):
# 1.从数据库中查询数据
stu_list = models.Student.objects.all()
# 2.序列化数据,获取序列化对象
ser = StuModelSer(instance=stu_list, many=True)
# 3.返回数据给客户端
return Response(ser.data, status=status.HTTP_200_OK)
def post(self, request):
# 1.序列化,获取到的数据
ser = StuModelSer(data=request.data)
if ser.is_valid(): # 2.验证数据
ser.save() # 3.保存数据
return Response(ser.data, status=status.HTTP_201_CREATED)
return Response({"message": ser.errors}, status=status.HTTP_400_BAD_REQUEST)
class StuApiViews(APIView):
"""获取1个和修改,删除的接口"""
def get(self, request, pk):
# 1.从数据库中查询数据
try:
student = models.Student.objects.get(pk=pk)
except models.Student.DoesNotExist:
return Response({"message": "数据不存在"}, status=status.HTTP_404_NOT_FOUND)
# 2.序列化数据,获取序列化对象
serializer = StuModelSer(instance=student)
# 3.返回数据给客户端
return Response(serializer.data, status=status.HTTP_200_OK)
def put(self, request, pk):
# 1.从数据库中查询数据
try:
student = models.Student.objects.get(pk=pk)
except models.Student.DoesNotExist:
return Response({"message": "数据不存在"}, status=status.HTTP_404_NOT_FOUND)
# 2.序列化提交进来数据
serializer = StuModelSer(instance=student, data=request.data)
# 3. 验证数据和保存
serializer.is_valid(raise_exception=True)
serializer.save()
# 4.返回数据给客户端
return Response(serializer.data, status=status.HTTP_200_OK)
def delete(self, request, pk):
try:
models.Student.objects.get(pk=pk).delete()
except models.Student.DoesNotExist:
return Response({"message": "数据不存在"}, status=status.HTTP_404_NOT_FOUND)
return Response({"message": "ok"}, status=status.HTTP_204_NO_CONTENT)
#4.urls.py
from django.urls import path, re_path
from rest_framework.routers import DefaultRouter
from . import views
urlpatterns = [
path('stu/', views.StuApiView.as_view()),
re_path(r'^stu/(?P\d+)/#39;, views.StuApiViews.as_view()),
]
通用视图类的主要作用就是把视图中的独特代码抽离出来,让视图方法中的代码更加简洁。
主要增加了操作序列化器和数据查询的方法,作用是为了mixin扩展类的执行提供方法支持,通常在使用时,可以搭配一个或多个mixin扩展类。
常用属性
基本方法
继承了APIView当出现一个视图类中调用多个序列化器时,
可以通过条件判断在get_serializer_class方法中通过返回不同的序列化器类名,
就可以让视图执行不同的序列化器对象。
class StuGenericAPIView(GenericAPIView):
def get_serializer_class(self): #视图中使用多个序列化器
if self.request.method.lower() == "put":
return StuModelSer
else:
return StuSer
#上面是使用2个序列化器,这个是,只使用一个序列化器
# serializer_class = StuModelSer
def get_queryset(self):
user = self.request.user
return user.accounts.all()
#重写视图类中的各种方法时。
class UserList(generics.ListCreateAPIView):
queryset = User.objects.all()
serializer_class = UserSerializer
permission_classes = (IsAdminUser,)
def list(self, request):
# 注意使用`get_queryset()`而不是`self.queryset`
queryset = self.get_queryset()
serializer = UserSerializer(queryset, many=True)
return Response(serializer.data)
def get_object(self):
queryset = self.get_queryset()
filter = {}
for field in self.multiple_lookup_fields:
filter[field] = self.kwargs[field]
obj = get_object_or_404(queryset, **filter)
self.check_object_permissions(self.request, obj)
return obj
"""通用视图类"""
#model.py和serializer.py的内容跟APIview一样
#3.views.py
from rest_framework.generics import GenericAPIView
class StuGenericAPIView(GenericAPIView):
queryset = models.Student.objects.all()
serializer_class = StuModelSer
def get(self, request): # 获取所有数据
# 1.从数据库中查询数据
queryset = self.get_queryset()
# 2.序列化数据
serializer = self.get_serializer(instance=queryset, many=True)
# 3.返回数据给客户端
return Response(serializer.data, status=status.HTTP_200_OK)
def post(self, request): # 添加一条数据
# 1.获取客户端提交的数据,实例化序列化器
serializer = self.get_serializer(data=request.data)
# 2.反序列化,保存数据到数据库
serializer.is_valid(raise_exception=True)
serializer.save()
# 3.把新增的数据返回给客户端
return Response(serializer.data, status=status.HTTP_201_CREATED)
class StuGenericAPIViews(GenericAPIView):
queryset = models.Student.objects.all()
serializer_class = StuModelSer
def get(self, request, pk): # 获取一条数据
# 1.从数据库中查询数据
instance = self.get_object()
# 2.序列化数据
serializer = self.get_serializer(instance=instance)
# 3.返回数据给客户端
return Response(serializer.data, status=status.HTTP_200_OK)
def put(self, request, pk): # 更新一条数据
# 1.从数据库中查询数据
instance = self.get_object()
# 2.序列化提交进来数据
serializer = self.get_serializer(instance=instance, data=request.data)
# 3. 验证数据和保存
serializer.is_valid(raise_exception=True)
serializer.save()
# 4.返回数据给客户端
return Response(serializer.data, status=status.HTTP_200_OK)
def delete(self, request, pk): # 删除一条数据
# 1.根据pk值获取要删除的数据
self.get_object().delete()
# 2.返回结果
return Response({"message": "ok"}, status=status.HTTP_204_NO_CONTENT)
#4.urls.py,新增genericAPIView视图
urlpatterns = [
# APIView
path('stu/', views.StuApiView.as_view()),
re_path(r'^stu/(?P\d+)/#39;, views.StuApiViews.as_view()),
# GenericAPIView
path('gstu/', views.StuGenericAPIView.as_view()),
re_path(r'^gstu/(?P\d+)/#39;, views.StuGenericAPIViews.as_view()),
]
结合GenericAPIView实现通用视图方法的简写操作,
提供一个 .list(request, *args, **kwargs) 方法,实现了列出一个查询集。如果查询集已填充,则返回 200 OK 响应,并将 queryset 的序列化表示形式作为响应的主体。响应数据可以设置分页。
提供 .create(request, *args, **kwargs) 方法,实现创建和保存新模型实例。如果创建了一个对象,则会返回一个 201 Created 响应,并将该对象的序列化表示形式作为响应的主体。如果表示包含名为 url 的键,则响应的 Location header 将填充该值。如果为创建对象提供的请求数据无效,则将返回 400 Bad Request 响应,并将错误细节作为响应的主体。
提供 .retrieve(request, *args, **kwargs) 方法,该方法实现在响应中返回现有的模型实例。如果可以获取对象,则返回 200 OK 响应,并将对象的序列化表示作为响应的主体。否则,将返回一个 404 Not Found
提供 .update(request, *args, **kwargs) 方法,实现更新和保存现有模型实例
还提供了一个 .partial_update(request, *args, **kwargs) 方法,它与更新方法类似,只是更新的所有字段都是可选的。这允许支持 HTTP PATCH 请求。
如果成功更新对象,则返回 200 OK 响应,并将对象的序列化表示形式作为响应的主体。如果提供的用于更新对象的请求数据无效,则将返回 400 Bad Request 响应,并将错误细节作为响应的主体。
提供一个 .destroy(request, *args, **kwargs) 方法,实现现有模型实例的删除。如果一个对象被删除,则返回一个 204 No Content ,否则它将返回一个 404 Not Found。
#model.py和serializer.py的内容跟APIview一样
#1.views.py
from rest_framework.mixins import (
ListModelMixin, # 获取多条数据,list
CreateModelMixin, # 添加一条数据,create
RetrieveModelMixin, # 获取一条数据 retrieve
UpdateModelMixin, # 更新一条数据 update
DestroyModelMixin # 删除一条数据 destroy
)
class StuMixinView(GenericAPIView, ListModelMixin, CreateModelMixin):
queryset = models.Student.objects.all()
serializer_class = StuModelSer
def get(self, request): # 查询所有数据
return self.list(request)
def post(self, request): # 新增一条数据
return self.create(request)
class StuMixinViews(GenericAPIView,RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin):
queryset = models.Student.objects.all()
serializer_class = StuModelSer
def get(self, request, pk): # 查询一条数据
return self.retrieve(request, pk=pk)
def put(self, request, pk): # 修改一条数据
return self.update(request, pk=pk)
def delete(self, request, pk): # 删除一条数据
return self.destroy(request, pk=pk)
#2.urls.py
urlpatterns = [
# APIView
path('stu/', views.StuApiView.as_view()),
re_path(r'^stu/(?P\d+)/#39;, views.StuApiViews.as_view()),
# GenericAPIView
path('gstu/', views.StuGenericAPIView.as_view()),
re_path(r'^gstu/(?P\d+)/#39;, views.StuGenericAPIViews.as_view()),
# mixins
path('mstu/', views.StuMixinView.as_view()),
re_path(r'^mstu/(?P\d+)/#39;, views.StuMixinViews.as_view()),
]
具体的通用视图。通常情况下,你应该都是使用的它们,除非需要高度的自定义行为。
ListAPIView = GenericAPIView + ListModelMixin #获取多条数据
RetrieveAPIView = GenericAPIView + RetrieveModelMixin #获取一个数据
CreateAPIView = GenericAPIView + CreateModelMixin #添加一条数据
UpdateAPIView = GenericAPIView + UpdateModelMixin #更新一条数据
DestroyAPIView = GenericAPIView + DestroyModelMixin #删除一条数据
#组合视图子类
ListCreateAPIView = ListAPIView + CreateAPIView
RetrieveUpdateAPIView = RetrieveAPIView + UpdateAPIView
RetrieveDestroyAPIView = RetrieveAPIView + DestroyAPIView
RetrieveUpdateDestroyAPIView = RetrieveAPIView + UpdateAPIView + DestroyAPIView
仅用于创建实例。提供一个 post 请求的处理方法。继承自:GenericAPIView, CreateModelMixin
仅用于读取模型实例列表。提供一个 get 请求的处理方法。继承自:GenericAPIView, ListModelMixin
仅用于查询单个模型实例。提供一个 get 请求的处理方法。继承自:GenericAPIView, RetrieveModelMixin
仅用于删除单个模型实例。提供一个 delete 请求的处理方法。继承自:GenericAPIView, DestroyModelMixin
仅用于更新单个模型实例。提供 put 和 patch 请求的处理方法。继承自:GenericAPIView, UpdateModelMixin
既可以获取也可以实例集合,也可以创建实例列表。提供 get 和 post 请求的处理方法。继承自:GenericAPIView, ListModelMixin,CreateModelMixin
既可以查询也可以更新单个实例。提供 get,put 和 patch 请求的处理方法。继承自:GenericAPIView, RetrieveModelMixin,UpdateModelMixin
既可以查询也可以删除单个实例。提供 get 和 delete 请求的处理方法。继承自:GenericAPIView, RetrieveModelMixin,DestroyModelMixin
同时支持查询,更新,删除。提供 get,put,patch 和 delete 请求的处理方法。继承自:GenericAPIView, RetrieveModelMixin,UpdateModelMixin,DestroyModelMixin
#model.py和serializer.py的内容跟APIview一样
#1.views.py
from rest_framework.generics import (
ListAPIView,
CreateAPIView,
RetrieveAPIView,
UpdateAPIView,
DestroyAPIView,
ListCreateAPIView,
RetrieveUpdateAPIView,
RetrieveDestroyAPIView,
RetrieveUpdateDestroyAPIView,
)
# 获取所有和添加一条数据的视图类
class StudentSonView(ListCreateAPIView):
queryset = models.Student.objects.all()
serializer_class = StuModelSer
# 获取一条,修改一条,删除一条的视图类
class StudentSonViews(RetrieveUpdateDestroyAPIView):
queryset = models.Student.objects.all()
serializer_class = StuModelSer
#2.urls.py
urlpatterns = [
...
# 视图子类
path('sstu/', views.StudentSonView.as_view()),
re_path(r'^sstu/(?P\d+)/#39;, views.StudentSonViews.as_view()),
]
留言与评论(共有 0 条评论) “” |