DRF之View、APIView以及GenericAPIView

一、APIView[基本视图类]

序列化后前端展示都是json数据,反序列化(post、put)也以json数据格式输入,这种用法存在很大的局限性,如果前端想以application/x-www-form-urlencoded或者其它的格式输入、或者返回的数据想以html页面的方式展示,这需要使用到另一个视图类,APIView,它对django中的View做了一系列拓展,如:认证、授权、限流和不同请求数据的解析等等

APIView是REST framwork提供的所有视图类的基类,继承自Django的View父类

APIView与View的不同区别:

  • 传入到视图方法中的是REST framwork的Request对象,而不是Django的HttpRequest对象

  • 视图方法可以返回Response对象,自动处理(根据请求头的参数)为符合前端要求的格式

  • 任何APIException异常都会被捕获到,并且处理成合适的响应信息

  • 重新声明了一个新的as_view方法,并在dispatch()进行路由分发前,会对请求进行身份认证、权限检查、流量控制

APIView除了继承了View原有的属性方法外,还新增了类属性:

  • authentication_classes列表或元组,身份认证类

  • permission_classes列表或元组,权限检查类

  • throttle_classes列表或元组,流量控制类

在APIView中仍可以以常规的类视图定义方法来实现get()、post()或者其他请求方式的方法。

APIView代码如下:

views.py

from rest_framework import status
from rest_framework.views import APIView
from rest_framework.response import Response
from .serialiazers import StudentModelSerializer
from stuapi.models import Students
from rest_framework.generics import GenericAPIView

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

GET  /demo/students/<pk>   获取一个学生信息
PUT  /demo/students/<pk>   更新一个学生信息
DELETE  /demo/students/<pk>   删除一个学生信息
"""
"""APIVIew基本视图类"""
class StudentAPIView(APIView):
    def get(self, request):
        """获取所有学生信息"""
        # 1.从数据库中读取学生信息
        student_list = Students.objects.all()
        # 2.实例化序列化器,获取序列化器对象
        serializer = StudentModelSerializer(instance=student_list,many=True)
        # 3.转换数据并返回给客户端
        return Response(serializer.data, status=status.HTTP_200_OK)

    def post(self, request):
        """添加一条学生信息"""
        # 1.获取客户端提交的数据,实例化序列化器,获取实例化对象
        serializer = StudentModelSerializer(data=request.data)
        # 2.反序列化(数据验证,保存到数据库)
        serializer.is_valid(raise_exception=True)
        serializer.save()
        # 3.返回新增的模型数据给客户端
        return Response(serializer.data, status=status.HTTP_201_CREATED)

class StudentInfoAPIView(APIView):
    def get(self, request, pk):
        """获取一条数据"""
        # 1.根据pk值获取一条数据
        try:
            student = Students.objects.get(pk=pk)
        except Students.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)
        # 2.实例化序列化器对象
        serializer = StudentModelSerializer(instance=student)
        # 3.转换数据,并返回给客户端
        return Response(serializer.data, status=status.HTTP_200_OK)

    def put(self, request, pk):
        """更新一条数据"""
        try:
            student = Students.objects.get(pk=pk)
        except Students.DoesNotExist:
            return Response(status=status.HTTP_404_NOT_FOUND)
        # 实例化序列化对象,获取客户端传入的数据
        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:
            Students.objects.get(pk=pk).delete()
        except Students.DoesNotExist:
            pass
        return Response(status=status.HTTP_204_NO_CONTENT)

urls.py

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


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

serialiazer.py

from rest_framework import serializers
from stuapi.models import Students

class StudentModelSerializer(serializers.ModelSerializer):
    class Meta:
        model = Students
        fields = "__all__"
        # 设置年龄限制,并设置报错信息
        extra_kwargs = {
            "age":{
                "max_value":25,
                "error_messages": {
                    "max_value":"年龄不能超过25岁!",
                }
            }
        }

models.py

from django.db import models

# Create your models here.


class Students(models.Model):
    ##学生信息
    name = models.CharField(max_length=100,verbose_name="姓名")
    sex = models.BooleanField(default=1,verbose_name="性别")
    age = models.IntegerField(verbose_name="年龄",help_text="年龄不能小于0")
    classmate = 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

展示图:

二、GenericAPIView[通用视图类]

通用视图类主要作用就是把视图中的独特代码抽取出来,让视图方法中的代码更加通用,方便把通用代码进行简写。

from rest_framework.generics import GenericAPIView

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

提供的关于序列化器使用的属性与方法

  • 属性:

  • serializer_class 指明试图使用的序列化器类

  • 方法:

  • get_serializer_class(self) 当出现一个视图类中调用多个序列化器时,那么可以通过条件判断在get_serializer_class方法中通过返回不同的序列化器类名就可以让视图方法执行不同的序列化器对象了。

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

    def get(self, request):
        """获取所有学生信息"""
        # 1.从数据库中读取信息
        queryset = self.queryset
        # 2.序列化
        serializer = self.get_serializer(instance=queryset, many=True)

        return Response(serializer.data)
  • 属性:

  • queryset指明使用的数据查询集

  • 方法:

class StudentInfoGenericAPIView(GenericAPIView):
    queryset = Students.objects.all()
    serializer_class = StudentModelSerializer

    def get(self, request, pk):
        """获取一个数据"""
        # 1.通过pk值获取对应数据
        instance = self.get_object()
        # 2.序列化
        serializer = self.get_serializer(instance=instance)

        return Response(serializer.data)

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值