drf- 视图

一 视图基类

1 APIView

from rest_framework.views import APIView

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

APIView与View的不同之处在于:

传入到视图方法中的是REST framework的Request对象,而不是Django的HttpRequeset对象;
视图方法可以返回REST framework的Response对象,视图会为响应数据设置(render)符合前端要求的格式;
任何APIException异常都会被捕获到,并且处理成合适的响应信息;
走的是APIView的dispatch()分发,在进行dispatch()分发前,会对请求进行身份认证、权限检查、流量控制。

支持定义的属性:

authentication_classes 列表或元祖,身份认证类
permissoin_classes 列表或元祖,权限检查类
throttle_classes 列表或元祖,流量控制类
在APIView中仍以常规的类视图定义方法来实现get() 、post() 或者其他请求方式的方法。

基于APIView写5个视图接口:

models.py

class Book(models.Model):
    name=models.CharField(max_length=32)
    price=models.DecimalField(max_digits=5,decimal_places=2)
    publish=models.CharField(max_length=32)

ser.py

class BookSerializer(serializers.ModelSerializer):  # 继承模型类序列化器,不用自己写字段对应表模型
    class Meta:
        model=Book
        fields='__all__'

urls.py

path('books/', views.BookView.as_view()),                        # 查所有、新增
re_path('books/(?P<pk>\d+)', views.BookDetailView.as_view()),    # 查单个、修改、删除

views.py

from rest_framework.views import APIView
from app01.models import Book
from app01.ser import BookSerializer

class BookView(APIView):
    def get(self,request):
        book_list=Book.objects.all()
        book_ser=BookSerializer(book_list,many=True)
        return Response(book_ser.data)
    
    def post(self,request):
        book_ser = BookSerializer(data=request.data)
        if book_ser.is_valid():
            book_ser.save()
            return Response(book_ser.data)
        else:
            return Response({'status':1,'msg':'校验失败'})


class BookDetailView(APIView):
    def get(self, request, pk):
        book = Book.objects.filter(pk=pk).first()
        book_ser = BookSerializer(book)
        return Response(book_ser.data)

    def put(self, request, pk):
        book = Book.objects.filter(pk=pk).first()
        book_ser = BookSerializer(instance=book,data=request.data)
        if book_ser.is_valid():
            book_ser.save()
            return Response(book_ser.data)
        else:
            return Response({'status': 1, 'msg': '校验失败'})

    def delete(self, request, pk):
        ret=Book.objects.filter(pk=pk).delete()
        return Response({'status': 0, 'msg': '删除成功'})

2 GenericAPIView

from rest_framework.generics import GenericAPIView

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

2.1 属性

属性名 含义
serializer_class 指明视图使用的序列化器, 表模型使用的序列化器
queryset 指明使用的数据查询集,queryset对象,表模型的查询结果
pagination_class 指明分页控制类
filter_backends 指明过滤控制后端

2.2 方法

方法名 含义
get_serializer_class(self) 重写此方法可以满足同一个视图类中需要调用多个序列化器的要求
get_serializer(self, *args, **kwargs)

返回表模型使用的序列化器

注意:该方法在提供序列化器对象的时候,会向序列化器对象的context属性补充三个数据:request、format、view,这三个数据对象可以在定义序列化器时使用
request 当前视图的请求对象
view 当前请求的类视图对象
format 当前请求期望返回的数据格式

get_queryset(self) 返回视图使用的查询集,哪个视图类的对象调用,就是查找它的queryset属性,返回的该视图类表模型查询结果
get_object(self) 返回单个视图模型类对象,从视图类配置的queryset对象中获取一个,针对单个对象
该方法会默认使用APIView提供的check_object_permissions方法检查当前对象是否有权限被访问

2.3 get_queryset() 与 get_serializer() 方法 

"""
        get_queryset方法:
        视图类的对象调用get_queryset方法,查找顺序:对象-->视图类-->GenericAPIView类
        queryset = self.queryset 对象.类属性-->查找顺序:对象-->视图类-->即表模型查询结果-->return
        作用:把queryset类属性写活了,全局定义时,对应的是哪个表模型,get_queryset()返回的就是这个模型的查询结果

        get_serializer方法:
        视图类的对象调用get_serializer方法,查找顺序:对象-->视图类-->GenericAPIView类
        它内部又调用了两个方法,最终返回serializer_class(*args, **kwargs)-->即选择的序列化器,并且可以传参
        作用: serializer_class属性写活了,全局定义时,对应的序列化器,都从这个方法中获取
"""

2.4 基于GenericAPIView写5个视图接口

表模型和序列化器跟基于APIView写接口一样,改变的是路由和视图。

urls.py

path('books2/', views.Book2View.as_view()),
re_path('books2/(?P<pk>\d+)', views.Book2DetailView.as_view()),

views.py

from rest_framework.generics import GenericAPIView
from app01.ser import BookSerializer,
from app01.models import Book

class Book2View(GenericAPIView):      
    queryset = Book.objects.all()        # queryset要传queryset对象,查询所有的图书
    serializer_class = BookSerializer    # serializer_class使用哪个序列化类来序列化这堆数据
    def get(self,request):
        book_list=self.get_queryset()
        book_ser=self.get_serializer(book_list,many=True)
        return Response(book_ser.data)
    
    def post(self,request):
        book_ser = self.get_serializer(data=request.data)
        if book_ser.is_valid():
            book_ser.save()
            return Response(book_ser.data)
        else:
            return Response({'status':1,'msg':'校验失败'})


class Book2DetailView(GenericAPIView):
    queryset = Book.objects.all() 
    serializer_class = BookSerializer
    def get(self, request,pk):
        book = self.get_object()    # get_object方法,从queryset对象中获取单个对象
        book_ser = self.get_serializer(book)
        return Response(book_ser.data)

    def put(self, request,pk):
        book = self.get_object()
        book_ser = self.get_serializer(instance=book,data=request.data)
        if book_ser.is_valid():
            book_ser.save()
            return Response(book_ser.data)
        else:
            return Response({'status': 1, 'msg': '校验失败'})

    def delete(self,request,pk):
        ret=self.get_object().delete()
        return Response({'status': 0, 'msg': '删除成功'})

2.5 作用

通用的视图类模板,任何表模型只要写视图类,配置好两个类属性,5个接口代码不用变动。如上例中,写了Book表的5个接口,如果需要再写一个Publish表的5个接口,只需要修改 queryset=Publish.objects.all() 和 serializer_class=PublishSerializer 两个属性,增删改查接口的代码不用修改。

posted @   不会钓鱼的猫  阅读(22)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· winform 绘制太阳,地球,月球 运作规律
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示