栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Django restframework重写get

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Django restframework重写get


活动地址:CSDN21天学习挑战赛

当view继承restframework的generics.ListAPIView的接口后,需要定义serializer_class实现数据的序列化,但是往往我们写业务逻辑时不确定具体的序列化class,这时候据需要根据传递的参数或者路由(url)来动态配置serializer_class,那么如何动态配置序列化类serializer_class呢?

get_serializer_class(self)介绍

在restframework的GenericAPIView类有get_serializer_class(self)方法,调用get_serializer_class(self)方法时默认返回设置的serializer_class序列化类,只要在我们的view中重写get_serializer_class(self)方法即可实现动态配置serializer_class。

get_serializer_class(self)源码如下:

def get_serializer_class(self):
    """
    Return the class to use for the serializer.
    Defaults to using `self.serializer_class`.

    You may want to override this if you need to provide different
    serializations depending on the incoming request.

    (Eg. admins get full serialization, others get basic serialization)
    """
    assert self.serializer_class is not None, (
        "'%s' should either include a `serializer_class` attribute, "
        "or override the `get_serializer_class()` method."
        % self.__class__.__name__
    )

    return self.serializer_class

官方文档: https://www.django-rest-framework.org/api-guide/generic-views/#get_serializer_classself

重写get_serializer_class(self)

重写get_serializer_class(self)方法实现动态配置序列化类,这里需要注意的是如果重写get_serializer_class(self)一定要返回一个序列化类,如果没有返回一个序列化类即使定义了serializer_class也会报错。

还有一个问题需要注意,当自定义序列化类后对应的model也需要根据自定义的序列化类改变,这样在调用self.get_serializer(page, many=True, request=request)方法后才可以正常序列化数据,但是如何动态获取model实现查询queryset呢?
这时候可以通过调用重写的get_serializer_class()方法获取序列化类,再根据序列化中的Meta类获取实体类model,然后实现数据查询。

完整的代码如下:

class Menus(generics.ListAPIView):
    renderer_classes = [TemplateHTMLRenderer]
    serializer_class = ArticlesSerializer  # 定义默认序列化类
    pagination_class = Pagination          # 定义翻页类(Pagination继承PageNumberPagination重写)
    
    # 重写get_serializer_class(self)实现动态配置serializer_class
    def get_serializer_class(self):
        menu = self.request.GET.get("menu")
        if menu == "categories":
            return CategoriesArticlesSerializer
        elif menu == "tags":
            return TagsArticlesSerializer
        else:
            return super().get_serializer_class()  # 获取父类的get_serializer_class(),也就serializer_class配置的序列化类

    def list(self, request):
        menu = request.GET.get("menu")
        Serializer = self.get_serializer_class()  # 获取序列化类
        model = Serializer.Meta.model             # 根据序列化类获取model
        queryset = model.objects.all()            # 查询数据queryset
        page = self.paginate_queryset(queryset)   # 获取分页数据queryset
        if page is not None:
            serializer = self.get_serializer(page, many=True, request=request)    # 实现数据序列化
            return self.get_paginated_response({'articles': serializer.data, "template_name": '%s.html' % menu})
        serializer = self.get_serializer(instance=queryset, many=True)
        return Response({"data": {'articles': serializer.data, template_name='%s.html' % menu)
小结

上面的代码中pagination_class = Pagination Pagination类是继承PageNumberPagination,重写了get_paginated_response方法,实现页码、总页码、上一页、下一页和总条数等计算和相关message、code信息,这里后面文章也会介绍。

还有此篇文章renderer_classes渲染器用的Django模板,调用了TemplateHTMLRenderer,通过定义template_name实现数据渲染的html,这里由于需要动态调用不同的html,所以把template_name放在了Response进行指定,但是这样不够优雅,可以通过重写get_template_names方法自定义模板界面,这里后面文章也会介绍。

最后通过在实现自定义序列化类,学习了djangorestframework的GenericAPIView类源码,看到所有的restframework的apiview都继承了GenericAPIView类。djangorestframework提供了丰富的类视图、Mixin扩展类,简化视图的编写。此篇文档就到这里,后面会逐步对djangorestframework其他功能进行扩展介绍,包括序列化、反序列化、身份认证和权限认证等,敬请期待。

此篇文章如果对你有帮助,请点赞收藏加关注。如果有疑问可以评论留言哈。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1036965.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号