源码分析Django rest_framework中GenericAPIView的使用方法和与APIView的区别


前言

如果想了解APIView的执行流程可点击APIView,可以打开项目复制代码,跟着本文一步一步分析,加快理解,如果想要快速了解GenericAPIView,可以直接跳到总结

一、GenericAPIView是什么?

`GenericAPIView`是Django REST framework中提供的一个通用视图类,用于简化编写基于类的API视图。通过继承`GenericAPIView`,开发者可以更快速地创建API视图,而不必从头开始编写所有逻辑。`GenericAPIView`提供了一些通用的方法和属性,以便处理常见的HTTP请求,如GET、POST、PUT、DELETE等。它还与不同类型的Mixin类结合使用,以提供不同类型的功能,例如列表视图、创建视图、更新视图、删除视图等。

二、源码分析

1.实例代码

代码如下(示例):

urls.py:

from django.urls import path,re_path
from api import views#api是我项目代码名称,根据自己情况去改

urlpatterns = [

    path('api/date/',views.DateGenericAPIView.as_view()),
    re_path('api/date/(?P<pk>\d+)',views.DatelistGenericAPIView.as_view()),]

models.py:

class Date(models.Model):
    name = models.CharField(verbose_name="名字",max_length=10,)
    age= models.IntegerField(verbose_name="年纪")
    title= models.CharField(max_length=255, verbose_name="标题")

 view.py:(GenericAPIView代码)

from rest_framework.generics import GenericAPIView
from api import models
from django.views import View
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import serializers


class DateGenericSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Date
        fields = "__all__"


class DateGenericAPIView(GenericAPIView):
    serializer_class = DateGenericSerializer
    queryset = models.Date.objects.all()

    def get(self, request, *args, **kwargs): #查看全部信息
        serializer = self.get_serializer(instance=self.get_queryset(), many=True)
        return Response(serializer.data)

    def post(self, request, *args, **kwargs): #增加信息
        serializer = self.get_serializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)


class DatelistGenericAPIView(GenericAPIView):
    serializer_class = DateGenericSerializer
    queryset = models.Date.objects.all()

    def get(self, request, *args, **kwargs):  #查看单个信息
        serializer = self.get_serializer(instance=self.get_object(), many=False)
        return Response(serializer.data)

    def put(self, request, *args, **kwargs):  #修改信息
        serializer = self.get_serializer(data=request.data, instance=self.get_object())
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)

    def delete(self, request, *args, **kwargs): #删除信息
        self.get_object().delete()
        return Response()

  view.py:(APIView代码)

from api import models
from django.views import View
from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import serializers

class DateGenericSerializer(serializers.ModelSerializer):
    class Meta:
        model = models.Date
        fields = "__all__"


class DateGenericAPIView(APIView):
    def get(self, request,*args,**kwargs):
        instance = models.Date.objects.all()
        # 2.序列化
        ser = DateGenericSerializer(instance=instance, many=False)
        # 3.返回
        return Response({"status": True, "data": ser.data})
    def post(self, request,*args,**kwargs):
        ser = DateGenericSerializer(data=request.data)
        if ser.is_valid():
            ser.save()
            return Response({"status": True, "data": ser.data})
class DatelistGenericAPIView(APIView):
    def get(self, request,*args,**kwargs):
        instance = models.Date.objects.filter(id=id).first()
        # 2.序列化
        ser = DateGenericSerializer(instance=instance, many=False)
        # 3.返回
        return Response({"status": True, "data": ser.data})
    def put(self, request, *args, **kwargs):
        instance = models.Date.objects.get(id=id).first()
        serializer =DateGenericSerializer(data=request.data, instance=instance)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
    def delete(self, request, *args, **kwargs):
        instance = models.Date.objects.get(id=id).first()
        instance.delete()
        return Response()

2.代码分析

CTRL+鼠标左键点击GenericAPIView进去查看

发现GenericAPIView类是继承APIView类,接下来我们重点了解以下的内容

Lookup_field ='pk‘,queryset = None,serializer class =None 这三个值

def get_queryset(self):
def get_object(self):
def get_serializer(self, *args,**kwargs):
def get_serializer_class(self): 这四个方法

我们先解释一下这四个方法:

这些方法是Django REST framework中的APIView类中的常用方法,用于处理视图的查询集、对象和序列化器。

- `$def get_queryset(self)$`:用于返回视图中要使用的查询集。可以根据需要对查询集进行过滤、排序等操作。
- `$def get_object(self)$`:用于返回视图中特定对象的实例。通常用于根据URL中的参数获取特定对象。
  
- `$def get_serializer(self, *args, **kwargs)$`:用于返回视图中要使用的序列化器实例。可以根据需要传入参数来定制序列化器。
  
- `$def get_serializer_class(self)$`:用于返回视图中要使用的序列化器类。通常与get_serializer方法一起使用,根据需要动态选择序列化器类。

了解这4个方法后,我们回来看view.py里面的 (GenericAPIView代码)和(APIView代码)(重点)

我们可以知道GenericAPIView类是继承APIView类,所以GenericAPIView类就是升级版的APIView类

1.在APIView类中进行序列化和反序列化对数据进行增删改查时要对数据进行反反复复的的查询重写,每一次增删改查时都是对数据的一次查询,例如:(models.Date.objects.get(id=id).first())

2.在APIView类还有就是序列化类的调用,增删改查也会反反复复的调用重写,例如:

serializer =DateGenericSerializer(data=request.data, instance=instance)

所以GenericAPIView在这两个方面进行了一些优化,所以现在我们现在来看(GenericAPIView代码)(实际就是APIView类的反反复复的重写调用的两个值,在GenericAPIView只要写一次就可以了)

这两个变量就是一开始我们注意的那3个值中的那两个值

serializer_class =DateGenericSerializer就是把序列化类放到这里

queryset = models.Date.objects.all()就是对数据的查询操作

这就是我们一开始分析的APIView那反反复复的执行的值,调用序列化类操作变成了

serializer = self.get_serializer(instance=self.get_queryset(), many=True)

self.get_serializer方法就是调用serializer_class =DateGenericSerialize,加括号就是执行这个序列化方法,

instance=self.get_queryset()就是拿到queryset = models.Date.objects.all(),赋值给instance

从这里来看实际上就是APIView的操作

接下来我们分析剩下的GenericAPIView代码

查看单个值,修改信息,删除信息这个几个操作,都需要通过ID值查询,但是我们拿到的是全部的值

queryset =models.Date.objects.all()

所以这个就是通过那三个值剩下的最后的一个值来设置的

 通过这个值我们就可以知道设置为’pk',id 我们是通过路由来传送

我们通过这样(?P<pk>)来设置类似“name”一样的属性设置为pk,然后通过*args, **kwargs

 来接收,也可以改成把*args, **kwargs改成pk也可以成功接收,剩下的方法也类似


总结

GenericAPIView就是继承APIView,GenericAPIView可以让代码变得更加简洁,当然还有其他方法让代码更加简单,比如mixin混合类,有兴趣的可以去了解一下,我以后也会更新这个知识点

  • 24
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值