Loading

22.通用视图GenericAPIView、属性和方法

generics.ListCreateAPIView
#源码
class ListCreateAPIView(mixins.ListModelMixin,
                        mixins.CreateModelMixin,
                        GenericAPIView):
    """
    Concrete view for listing a queryset or creating a model instance.
    """
    def get(self, request, *args, **kwargs):
        return self.list(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)
# 使用
# 导入generics
from rest_framework import generics
from ..models.models import Post # 模型类
from ..serializers import postSerializer # 序列化器


class PostList(generics.ListCreateAPIView):
    # 指定查询集
    queryset = Post.objects.all()
    # 指定序列化类
    serializer_class = postSerializer
 
从源码可以看出,generics.ListCreateAPIView继承了mixins.ListModelMixin, mixins.CreateModelMixin,GenericAPIView,里面写好了get和post方法使用了混合类的list和create方法,所以我们使用的时候,只需要定义queryset和serializer_calss,然后直接发送get、post请求就可以完成请求,如果需要功能扩展,可以重写get、post方法
 
GenericAPIView
 GenericAPIView继承APIView,将APIView的属性方法重 写扩展,并提供了一些新的方 属性
 
属性
 queryset
 """
 必须指定,用于从视图返回对象的查询结果集,通常,你必须设置此属性或者重写get_queryset()方法,
 如果你重写了一个视图的方法,你应该调用get_queryset()而不是直接访问该属性,因为queryset将被计算一次
 这些结果将为后续请求存储起来
 """
class PostList(generics.ListCreateAPIView):
    # 指定查询集
    queryset = Post.objects.all()
    # 指定序列化类
    serializer_class = postSerializer

    # 如果需要,可以重写queryset过滤一遍
    def get_queryset(self):
        ...
    def list(self, request):
        queryset = self.get_queryset() # 获queryset查询结果集
 
serializer_class
 """
 用户验证和反序列化输入以及用户序列号输出的serializer类,通常,你必须设置此属性或者重写get_serializer_class()方法
 """
class PostList(generics.ListCreateAPIView):
    # 指定查询集
    queryset = Post.objects.all()
    # 指定序列化类
    serializer_class = postSerializer
    # 如果有需求重写
    def get_serializer_class(self):
        if self.request.user.is_staff:
            return postSerializer
        return gettSerializer
        
    def list(self,requerst):
        queryset = self.get_queryset()
        serializer = self.get_serializer(queryset,many=True) # 获取serializer序列化器
 
lookup_field
"""
用于执行各个model实例的对下查找的model字段,默认为pk
注意:在使用超链接API时,如果需要使用自定义的值,需要确保在API和序列化类中都设置查找字段
"""
#url
path('run/<int:code>/', PostListDetail.as_view()),

#视图
class PostListDetail(mixins.RetrieveModelMixin,
                     mixins.UpdateModelMixin,
                     mixins.DestroyModelMixin,
                     generics.GenericAPIView):
    queryset = Post
    serializer_class = postSerializer
#不指定lookup_field ,默认就是pk,传值时只能是pk
    def get(self, request, pk):
        #APIView 不能使用get_object()方法获取参数值
        #继承APIView的其他扩展View,可以使用get_objcet()方法获取参数值,也可以直接传值
#指定lookup_field ,传值就是指定的值
lookup_field = 'test'
def get(self, request, test):
lookup_url_kwarg
"""
用于对象查找url关键字参数,他的url conf应该包括这应该与这个指相对于的关键字参数,如果取消设置
默认情况下使用与lookup_field相同的值
"""
#url
path('run/<str:code>/', PostListDetail.as_view()),
#视图
class PostListDetail(mixins.RetrieveModelMixin,
                     mixins.UpdateModelMixin,
                     mixins.DestroyModelMixin,
                     generics.GenericAPIView):
    queryset = Post
    serializer_class = postSerializer
    lookup_url_kwarg = 'code'
# 如果url内不包含lookup_url_kwarg的值,则会报错   
get_queryset()
"""
返回list视图中使用的查询集,该查询集还用做detail视图中的查找基础,默认返回由queryset属性指定的查询集
平时我们应该多使用这个方法,而不是直接访问self.queryset,因为self.queryset只会被提交一次
然后这些结果将为后续请求缓存起来,该方法可能会被重写以提供动态行为
"""
get_object()
"""
返回用于detail视图的对象实例,默认使用look_up_field参数过滤基本的查询集
该方法可以被重写以提供更复杂的行为,例如基于多个url参数的对象查找
"""
 
filter_queryset
"""
给定一个queryset,使用任何过滤器后端进行过滤,返回一个新的queryset
"""
 

posted @ 2022-07-20 19:33  木子七  阅读(234)  评论(0编辑  收藏  举报