You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Django Serializer中重复的用户校验逻辑抽离为独立结构?

解决方案:提取重复的请求验证逻辑

这里有两种简洁的实现方式,帮你把重复的验证逻辑抽离出来,符合代码复用的要求:

方式一:提取为工具函数

先把判断逻辑单独写成一个可复用的函数,放在项目的工具模块(比如utils.py)或者当前序列化器文件里:

def is_authenticated_user(request):
    # 检查请求是否存在且用户已认证
    return request is not None and not request.user.is_anonymous

然后修改你的两个序列化器,直接调用这个函数:

修改后的CustomUserSerializer

class CustomUserSerializer(UserSerializer):
    """ Сериализатор модели пользователя. """

    is_subscribed = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = User
        fields = [
            'id',
            'email',
            'username',
            'first_name',
            'last_name',
            'is_subscribed'
        ]

    def get_is_subscribed(self, obj):
        request = self.context.get('request')
        if not is_authenticated_user(request):
            return False
        return Subscription.objects.filter(
            user=request.user, author=obj
        ).exists()

修改后的RecipeSerializer

class RecipeSerializer(serializers.ModelSerializer):
    def get_is_subscribed(self, obj):
        request = self.context.get('request')
        if not is_authenticated_user(request):
            return False
        return Subscription.objects.filter(
            user=request.user, author=obj
        ).exists()

方式二:使用Mixin类(更符合Django序列化器的复用习惯)

如果后续还有更多序列化器需要用到这类验证逻辑,用Mixin类会更优雅:

class AuthenticatedUserMixin:
    def is_authenticated(self):
        request = self.context.get('request')
        return request is not None and not request.user.is_anonymous

让你的序列化器继承这个Mixin,直接调用内部方法:

修改后的CustomUserSerializer

class CustomUserSerializer(AuthenticatedUserMixin, UserSerializer):
    """ Сериализатор модели пользователя. """

    is_subscribed = serializers.SerializerMethodField(read_only=True)

    class Meta:
        model = User
        fields = [
            'id',
            'email',
            'username',
            'first_name',
            'last_name',
            'is_subscribed'
        ]

    def get_is_subscribed(self, obj):
        if not self.is_authenticated():
            return False
        return Subscription.objects.filter(
            user=self.context['request'].user, author=obj
        ).exists()

修改后的RecipeSerializer

class RecipeSerializer(AuthenticatedUserMixin, serializers.ModelSerializer):
    def get_is_subscribed(self, obj):
        if not self.is_authenticated():
            return False
        return Subscription.objects.filter(
            user=self.context['request'].user, author=obj
        ).exists()

两种方式的选择

  • 如果只是单一的验证逻辑要复用,工具函数足够简单直接;
  • 如果有多个和用户认证相关的逻辑要在序列化器之间共享,Mixin类的扩展性更好。

内容的提问来源于stack exchange,提问作者Rinat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 07:41:35