如何让Django Rest Framework序列化器区分处理GET与POST请求
解决Bookmark API返回字段显示为字符串而非ID的问题
要实现GET请求返回user、collection、tags的字符串形式,同时不影响现有POST/PUT/PATCH的逻辑,可以通过为Serializer添加只读字段来实现,无需修改原有的create方法。
修改后的BookmarkSerializer代码
from rest_framework import serializers from .models import Bookmark class BookmarkSerializer(serializers.ModelSerializer): # 只读字段,用于返回字符串形式的数据 user = serializers.StringRelatedField(read_only=True) collection = serializers.StringRelatedField(read_only=True, allow_null=True) tags = serializers.StringRelatedField(many=True, read_only=True) class Meta: model = Bookmark fields = "__all__" def create(self, validated_data): tags_data = validated_data.pop('tags', []) bookmark = Bookmark.objects.create(**validated_data) for tag_data in tags_data: bookmark.tags.add(tag_data) return bookmark
代码说明
StringRelatedField:这个字段会自动关联模型的
__str__方法返回值,刚好匹配你需要的字符串格式:user:依赖User模型的__str__方法(通常返回username,若你的User模型__str__不是username,可改用serializers.CharField(source='user.username', read_only=True))collection:依赖Collection模型的__str__方法(需确保Collection模型的__str__返回名称,比如return self.name)tags:因为是多对多关系,加上many=True,返回每个Tag的__str__值列表
read_only=True:标记这些字段为只读,意味着序列化器在处理POST/PUT/PATCH请求时会忽略这些字段,完全不影响原有的创建、更新逻辑,依然使用传入的ID来关联数据。
allow_null=True:针对collection字段(允许为null),避免当collection为None时序列化报错。
替代方案(自定义字段内容)
如果不想依赖模型的__str__方法,也可以用SerializerMethodField自定义返回内容:
class BookmarkSerializer(serializers.ModelSerializer): user = serializers.SerializerMethodField() collection = serializers.SerializerMethodField() tags = serializers.SerializerMethodField() class Meta: model = Bookmark fields = "__all__" def get_user(self, obj): return obj.user.username # 直接指定返回用户名 def get_collection(self, obj): return obj.collection.name if obj.collection else None # 自定义返回集合名称 def get_tags(self, obj): return [tag.name for tag in obj.tags.all()] # 自定义返回标签名称列表 def create(self, validated_data): # 保留原create方法不变 tags_data = validated_data.pop('tags', []) bookmark = Bookmark.objects.create(**validated_data) for tag_data in tags_data: bookmark.tags.add(tag_data) return bookmark
这种方式更灵活,能精准控制每个字段返回的内容,同样不会影响写操作逻辑。
内容的提问来源于stack exchange,提问作者Aditya Vaste
相关产品推荐
相关产品推荐

