Loading

两个视图基类

两个视图基类

9.1 APIView基本视图类

9.1.1 APIView与django的view的区别

View是Django默认的视图基类,APIView是REST framework提供的所有视图的基类, 继承自Django的View,对Django中的View进行了拓展,具备了认证、授权、限流、不同请求数据的解析的功能。

  • APIView的request与view的request不同

  • APIView具有身份验证,权限限制,限流等功能

    authentication_classes 身份认证
    permission_classes 权限检查
    throttle_classes 流量控制
    
  • APIView视图方法可以返回REST framework的Response对象,视图会为响应数据设置(render)符合前端要求的格式;

9.1.2 基于APIView实现五个接口

序列化器

from rest_framework import serializers
from app.models import studentsInfo


class StudentModelSerializer(serializers.ModelSerializer):
    """学生信息序列化器"""

    class Meta:
        model = studentsInfo
        fields = ["id", "name", "sex", "age", "classroom", "info"]
        read_only_fields = ["id"]
        extra_kwargs = {
            "age": {
                "min_value": 0,
                "max_value": 100,
                "error_messages": {
                    "min_value": "the age must be age>=0",
                    "max_value": "the age must be age<=100"
                }
            }
        }

视图

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from app.models import studentsInfo
from .serializers import StudentModelSerializer

"""
post /students/ 添加一个学生
GET  /students/ 获取所有学生信息

GET  /students/<pk>/获取一个学生信息
PUT  /students/<pk>/ 更新一个学生信息
DELETE /students/<pk>/ 删除一个学生信息

一个路由对应一个视图类,把5个api接口分为两个视图类来写
"""


class StudentView(APIView):
    def post(self, request):
        serializer = StudentModelSerializer(data=request.data)

        serializer.is_valid(raise_exception=True)

        serializer.save()

        return Response(serializer.data, status=status.HTTP_201_CREATED)

    def get(self, request):
        data = studentsInfo.objects.all()

        serializer = StudentModelSerializer(instance=data, many=True)

        return Response(serializer.data,status=status.HTTP_200_OK)


class StudentAPIView(APIView):
    def get(self, request, pk):
        try:
            student = studentsInfo.objects.get(id=pk)
        except studentsInfo.DoesNotExist:
            return Response({"message": "没有该学生的相关信息"},status=status.HTTP_204_NO_CONTENT)
        serializer = StudentModelSerializer(instance=student)
        return Response(serializer.data,status=status.HTTP_200_OK)

    def put(self, request, pk):
        try:
            student = studentsInfo.objects.get(id=pk)
        except studentsInfo.DoesNotExist:
            return Response({"message": "没有该学生的相关信息,您可以添加此学生哦!"}, status=status.HTTP_204_NO_CONTENT)
        serializer = StudentModelSerializer(instance=student, data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data, status=status.HTTP_201_CREATED)

    def delete(self, request, pk):
        try:
            studentsInfo.objects.get(id=pk).delete()
        except studentsInfo.DoesNotExist:
            return Response({"message": "没有该学生的相关信息,可能已经删除过啦"}, status=status.HTTP_204_NO_CONTENT)
        return Response({"message": "删除成功"}, status=status.HTTP_200_OK)

路由

from django.urls import path, re_path
from . import views

urlpatterns = [
    path('students/', views.StudentView.as_view()),
    re_path(r'^students/(?P<pk>\d+)/$', views.StudentAPIView.as_view())
]

总路由

from django.contrib import admin
from django.urls import path, include

urlpatterns = [
    path('viewdemo/', include('viewdemo.urls')),
]

9.2 GenericAPIView通用视图类

9.2.1 GenericAPIView的介绍

GenericAPIView 继承自 APIView,主要增加了操作序列化和数据库查询的方法,作用是为下面 Mixin 扩展类的执行提供方法支持。通常在使用时,可搭配一个或多个 Mixin 扩展类。

  • 指明视图使用的序列化器

① 通过属性:

serializer_class

② 通过方法:

get_serializer_class(self)

get_serializer(self, args, *kwargs)

  • 数据库查询的属性与方法

指明使用的数据查询集

① 通过属性

queryset

② 通过方法

get_queryset(self)

get_object(self)

9.2.2 基于GenericAPIView实现五个接口

视图

from rest_framework.generics import GenericAPIView
from rest_framework.response import Response
from rest_framework import status
from app.models import studentsInfo
from .serializers import StudentModelSerializer


"""GenericAPIView通用视图类"""


class StudentGenericAPIView(GenericAPIView):
    queryset = studentsInfo.objects.all()
    serializer_class = StudentModelSerializer

    def get(self, request):
        """获取所有数据"""
        queryset = self.get_queryset()
        serializer = self.get_serializer(instance=queryset, many=True)
        return Response(serializer.data)

    def post(self, request):
        """添加一名学生"""
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()

        return Response(serializer.data)


class StudentGenericAPIView2(GenericAPIView):
    queryset = studentsInfo.objects.all()
    serializer_class = StudentModelSerializer

    def get(self, request, pk):
        """获取一条数据"""
        queryset = self.get_object()
        serializer = self.get_serializer(instance=queryset)
        return Response(serializer.data)

    def put(self, request, pk):
        """修改一条数据"""
        instance = self.get_object()
        serializer = self.get_serializer(instance=instance, data=request.data)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        return Response(serializer.data)

    def delete(self, request, pk):
        """删除一条数据"""
        self.get_object().delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

路由

from django.urls import path, re_path
from . import views

urlpatterns = [
    # APIView
    path('students/', views.StudentView.as_view()),
    re_path(r'^students/(?P<pk>\d+)/$', views.StudentAPIView.as_view()),

    # GenericAPIView
    path('students2/', views.StudentGenericAPIView.as_view()),
    re_path(r'^students2/(?P<pk>\d+)/$', views.StudentGenericAPIView2.as_view()),

]
posted @ 2022-10-24 17:20  minqiliang  阅读(55)  评论(0编辑  收藏  举报
-->