如何将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
相关产品推荐
相关产品推荐

