改造REST-Framework,自定义修饰器为ViewSet中每个Action指定单独的Serializer

在 REST-Framework 的 ViewSet 中,一般是通过 ViewSet 类的 serializer_class 属性来指定视图所使用的 Serializer。

但是很多时候我们需要为 ViewSet 中的某个 Action 指定不同的 Serializer。 比如在 UserViewSet中有一个修改密码的 Action:change_password,我们需要单独为它指定一个 ChangePasswordSerializer。

根据官方文档,我们可以这样做,重写 ViewSet 类的 get_serializer_class 方法,自己实现判断逻辑返回需要的 Serializer。

    def get_serializer_class(self):
        if self.action == "change_password":
            return ChangePasswordSerializer
        return super(UserViewSet, self).get_serializer_class()

这样在 change_password 方法中我们就可以直接通过 self.get_serializer() 得到 ChangePasswordSerializer 对象了。

但是这不是一个优雅的解决方法,我们应该劲量避免代码中出现硬编码!!!

为了优雅的解决这个问题,我们需要实现一个方法装饰器和一个 Mixin 类。

继续阅读改造REST-Framework,自定义修饰器为ViewSet中每个Action指定单独的Serializer

使用Django自带的session和auth应用实现Token认证

Django的session和auth应用配合起来很方便的实现了身份认证和会话管理的功能。

现在我的项目在原有网站基础上需要另外提供一套API,只需要简单的一点拓展就可以在现有session和auth应用基础上实现基于Token的认证。

在自己的app下创建middleware.py文件,写一个自己的class,继承django.contrib.session.middleware模块下的SessionMiddleware类,并且重写process_request方法。

from django.conf import settings
from django.contrib.sessions.middleware import SessionMiddleware

class SessionTokenMiddleware(SessionMiddleware):

    def process_request(self, request):
        # 尝试从请求头中获取 Session Key
        session_key = request.META.get("HTTP_" + getattr(settings, "ACCESS_TOKEN_NAME", "Access-Token").replace("-","_").upper())
        if not session_key:
            super().process_request(request)
        else:
            request.session = self.SessionStore(session_key)

在处理请求时,先尝试从请求头中对应字段获取Token,即Session Key,并通过Session引擎获取Session对象。
如果请求头中没有包含Token字段,则调用父类方法。

继续阅读使用Django自带的session和auth应用实现Token认证