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

Django Rest Framework序列化器获取URL参数的问题

解决DRF分页场景下序列化器获取URL中user_id的问题

方案一:修改自定义分页器,支持传递额外Context

你的自定义分页器CustomPageNumberPagination的generate_response方法应该没处理序列化器的context参数,直接修改这个方法,让它接收并传递context即可:

修改分页器代码

class CustomPageNumberPagination(PageNumberPagination):
    def generate_response(self, queryset, serializer_class, request, **kwargs):
        page = self.paginate_queryset(queryset, request)
        if page is not None:
            # 获取视图传入的context,默认空字典
            context = kwargs.get('context', {})
            # 把request加入context(DRF序列化器默认会携带request到context)
            context['request'] = request
            serializer = serializer_class(page, many=True, context=context)
            return self.get_paginated_response(serializer.data)
        
        # 不分页场景同样传递context
        context = kwargs.get('context', {})
        context['request'] = request
        serializer = serializer_class(queryset, many=True, context=context)
        return Response(serializer.data)

视图中调用时传递context

def get(self, request, post_id, post_language_id, user_id):
    ...
    paginator = CustomPageNumberPagination()
    # 传入包含user_id的context
    response = paginator.generate_response(language_liked_data, PostLanguageLikedSerializer, request, context={'user_id': user_id})
    return response

方案二:直接从Request对象获取URL路径参数(更通用)

既然user_id是URL中的路径参数,你可以直接在序列化器中从request对象的parser_context里提取,不需要手动传context,分页/非分页场景都能用:

修改序列化器代码

class PostLanguageLikedSerializer(serializers.ModelSerializer):
    is_following = serializers.SerializerMethodField()
    ...
    class Meta:
        model = PostLanguageLike
        fields = [...,'is_following']
    
    def get_is_following(self, obj):
        # 从request的路径参数中直接获取user_id
        user_id = self.context['request'].parser_context['kwargs']['user_id']
        # 用exists()替代len(),查询性能更优
        is_following = UserFollowing.objects.filter(user_id=user_id, following_user_id=obj.user.id).exists()
        return is_following

这个方案无需修改视图和分页器,逻辑更简洁,推荐使用。

方案三:将user_id附加到Request对象上

在视图中把user_id放到request的自定义属性中,序列化器直接从request读取:

视图代码修改

def get(self, request, post_id, post_language_id, user_id):
    # 把user_id附加到request对象
    request.user_id = user_id
    ...
    paginator = CustomPageNumberPagination()
    response = paginator.generate_response(language_liked_data, PostLanguageLikedSerializer, request)
    return response

序列化器代码修改

def get_is_following(self, obj):
    user_id = self.context['request'].user_id
    is_following = UserFollowing.objects.filter(user_id=user_id, following_user_id=obj.user.id).exists()
    return is_following

注意:使用该方案时,要确保分页器的generate_response方法在实例化序列化器时,已将request传入context(DRF序列化器默认会自动包含request,只要分页器没覆盖这个逻辑即可)。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 01:55:32