如何在DRF的ModelSerializer中从视图传入额外字段sub_id?
给ModelSerializer添加动态sub_id字段的实现方法
第一步:修复视图中的查询逻辑
原视图的订阅记录查询逻辑有误,需按当前用户的user_id过滤SubscriptionsOrder,同时处理用户未订阅的边界情况,避免空指针报错:
修改后的views.py:
class SubscriptionView(APIView): def get(self, request): # 获取当前用户的订阅记录,无记录则返回None user_sub = SubscriptionsOrder.objects.filter(user_id=request.user).first() # 提取用户已订阅的计划ID,无订阅则设为None subscribed_plan_id = user_sub.plan_selected.id if user_sub and user_sub.plan_selected else None subscription_details = SubscriptionsPlans.objects.filter(is_deleted=False) # 将订阅ID传入序列化器上下文 user_serializer = SubscriptionSerializer(subscription_details, context={'subscribed_plan_id': subscribed_plan_id}) return Response(user_serializer.data)
第二步:修改序列化器,添加动态sub_id字段
使用SerializerMethodField生成动态sub_id字段,通过上下文传入的订阅ID判断当前计划是否被用户订阅:
修改后的serializer.py:
class SubscriptionSerializer(serializers.ModelSerializer): # 定义动态字段sub_id sub_id = serializers.SerializerMethodField() class Meta: model = SubscriptionsPlans # 将sub_id加入返回字段列表 fields = ['id', 'name', 'plan_type', 'plan_details', 'price', 'sub_id'] def get_sub_id(self, obj): # 从上下文获取用户已订阅的计划ID subscribed_plan_id = self.context.get('subscribed_plan_id') # 对比当前计划ID与订阅ID,返回布尔值 return obj.id == subscribed_plan_id
代码说明
SerializerMethodField会自动调用对应get_<字段名>方法生成字段值,这里即get_sub_id- 视图通过
context将用户已订阅的计划ID传给序列化器,让每个计划对象能独立判断自身是否被订阅 - 处理了用户未订阅、订阅记录为空的场景,避免程序崩溃
最终返回效果
修改后返回的JSON会与期望一致:
[ { "id": 1, "name": "Professional", "plan_type": "MONTHLY", "plan_details": "{'Details'}", "price": 50.0, "sub_id": true }, { "id": 2, "name": "Business", "plan_type": "MONTHLY", "plan_details": "{Business}", "price": 100.0, "sub_id": false } ]
内容的提问来源于stack exchange,提问作者ReaL_HyDRA
相关产品推荐
相关产品推荐

