Django序列化中ForeignKey显示指定值而非ID且兼容POST/PUT
解决Django序列化器ForeignKey字段显示关联模型指定字段且不影响增改请求的问题
方案1:使用SerializerMethodField(推荐)
这种方式既能自定义返回的字段值,又完全不破坏原有ForeignKey字段的增改逻辑,是最省心的处理方式。
实现步骤:
- 保留序列化器中原有的
room_num字段,用于POST/PUT请求时接收关联Rooms的ID - 添加一个自定义字段(比如
room_number),通过SerializerMethodField返回Rooms模型的room字段值
示例代码:
# serializers.py from rest_framework import serializers from .models import Registrations, Rooms class RegistrationSer(serializers.ModelSerializer): # 自定义字段,用于返回房间号 room_number = serializers.SerializerMethodField() class Meta: model = Registrations # 保留原room_num字段用于增改,同时加入自定义字段 fields = ['id', 'room_num', 'room_number', '其他字段'] # 替换为你的实际字段 def get_room_number(self, obj): # 关联对象存在时返回room字段值,否则返回None return obj.room_num.room if obj.room_num else None
效果说明:
- GET请求时,
room_number字段会显示对应房间的编号(Rooms的room字段值) - POST/PUT请求时,依然可以通过
room_num字段传入Rooms的ID完成关联,完全不影响原有业务逻辑
方案2:嵌套序列化器+写入专用字段
如果不需要通过原room_num字段写入数据,也可以用这种方式,但需要额外处理增改逻辑,步骤相对繁琐:
示例代码:
# serializers.py from rest_framework import serializers from .models import Registrations, Rooms class RoomMiniSer(serializers.ModelSerializer): class Meta: model = Rooms fields = ['room'] class RegistrationSer(serializers.ModelSerializer): # 只读的嵌套序列化器,用于返回房间号 room_num = RoomMiniSer(read_only=True) # 写入专用字段,接收Rooms的ID room_id = serializers.PrimaryKeyRelatedField(queryset=Rooms.objects.all(), write_only=True) class Meta: model = Registrations fields = ['id', 'room_num', 'room_id', '其他字段'] def create(self, validated_data): # 取出room_id,替换为room_num字段存入数据库 room_id = validated_data.pop('room_id') validated_data['room_num'] = room_id return super().create(validated_data) def update(self, instance, validated_data): # 更新时处理room_id字段 if 'room_id' in validated_data: room_id = validated_data.pop('room_id') instance.room_num = room_id instance.save() return super().update(instance, validated_data)
内容的提问来源于stack exchange,提问作者Qadyr Israfilov
相关产品推荐
相关产品推荐

