Django REST Framework序列化器如何获取外键关联的额外字段数据?
错误原因说明
你之前的写法不生效有两个核心原因:
- 接口返回的是Booking模型的序列化数据,你修改的是ChairSerializer,对应不上
- DRF序列化器的
fields配置不支持直接写ORM风格的双下划线跨表字段,需要显式定义关联字段
实现方案
方案1:使用SlugRelatedField(仅需返回chair name时最优)
不需要额外改动其他序列化器,直接修改BookingSerializer即可,返回结果会同时保留原有的chair ID和新增的chair name字段:
class BookingSerializer(serializers.ModelSerializer): # 显式定义关联字段,取chair的name属性 chair_name = serializers.SlugRelatedField( source='chair', slug_field='name', read_only=True ) class Meta: model = Booking # 新增字段加入fields列表,也可以直接写 '__all__' 自动识别 fields = ['id', 'chair', 'chair_name', 'day', 'user_name', 'user_created', 'date_created']
方案2:嵌套序列化器(需要返回Chair的多个字段时使用)
如果后续还需要返回chair的bookable等其他属性,可以直接嵌套ChairSerializer,返回的chair字段会是完整的对象:
class BookingSerializer(serializers.ModelSerializer): # 嵌套已有的ChairSerializer chair = ChairSerializer(read_only=True) class Meta: model = Booking fields = '__all__'
如果需要同时保留chair的ID值,可以额外加一个显式的chair_id字段:
class BookingSerializer(serializers.ModelSerializer): chair = ChairSerializer(read_only=True) chair_id = serializers.IntegerField(read_only=True) class Meta: model = Booking fields = ['id', 'chair', 'chair_id', 'day', 'user_name', 'user_created', 'date_created']
方案3:使用SerializerMethodField(有自定义处理逻辑时使用)
如果需要对返回的name做额外处理,可以用这个方案,灵活度最高:
class BookingSerializer(serializers.ModelSerializer): chair_name = serializers.SerializerMethodField() class Meta: model = Booking fields = ['id', 'chair', 'chair_name', 'day', 'user_name', 'user_created', 'date_created'] def get_chair_name(self, obj): # 这里可以加自定义处理逻辑 return obj.chair.name
性能优化建议
修改视图的查询语句,加上select_related提前关联查询Chair表,避免出现N+1查询问题:
@api_view(['GET']) def bookings_by_date(request, pk): bookings = Booking.objects.filter(day=pk).select_related('chair') serializer = BookingSerializer(bookings, many=True) return Response(serializer.data)
内容的提问来源于stack exchange,提问作者finethen
相关产品推荐
相关产品推荐

