Django Rest Framework自定义字段在create时未出现在attrs字典的问题
问题原因
你用的SerializerMethodField是只读字段,DRF只会在序列化(返回查询结果)时调用对应的get_teams方法生成数据,反序列化(处理POST请求)时会直接忽略这个字段,所以它不会被加入到validated_data(也就是validate方法里的attrs)中,自然没法做必填验证。
解决方案
把teams字段改成兼具读写能力的字段,用DictField(因为你的teams是字典结构),然后重写它的to_representation方法来实现原有的查询返回逻辑。这样POST时它会被正常解析到validated_data,GET时会返回你需要的自定义结构。
修改后的完整代码:
class MatchDaySerializer(serializers.ModelSerializer): # Validate if teams field exists in POST data def validate(self, attrs): if not "teams" in attrs: raise serializers.ValidationError({"teams": "This field is required"}) # 可额外添加teams结构验证,比如检查是否包含blue/orange/colors键等 return attrs # Serializer Fields matches = serializers.SerializerMethodField() # 替换SerializerMethodField为DictField,设置必填,重写序列化逻辑 teams = serializers.DictField(required=True) class Meta: model = MatchDay fields = [ 'id', 'date', 'matches', 'teams', ] # Returns match counter def get_matches(self, obj): if not hasattr(obj, 'id') or not isinstance(obj, MatchDay): return None return obj.match_counter # 重写teams字段的序列化方法,替代原来的get_teams def to_representation(self, instance): representation = super().to_representation(instance) # 原get_teams的逻辑移到这里 tickets_dict = MatchDayTicket.objects.filter(matchday=instance).values('player_id', 'team') teams_dict = { "blue": [], "orange": [], "colors": [], } for ticket in tickets_dict: team = ticket.pop('team') if team in teams_dict: teams_dict[team].append(ticket) representation['teams'] = teams_dict return representation def create(self, validated_data): # 现在可以直接从validated_data拿teams数据,不用再取initial_data teams_data = validated_data.pop('teams') matchday = MatchDay.objects.create(**validated_data) for team, players in teams_data.items(): for player_data in players: player = Player.objects.get(id=player_data['id']) MatchDayTicket.objects.create(matchday=matchday, player=player, team=team) return matchday
额外说明
- 如果你的
teams结构有特定格式要求,可以在validate方法里进一步验证,比如检查每个team对应的player列表是否包含有效的id,避免后续查询Player时报错。 - 这种方式让同一个字段在读写阶段分别执行不同逻辑,既满足POST时的必填验证和数据接收,又保留了GET时的自定义返回结构。
内容的提问来源于stack exchange,提问作者Put3k
相关产品推荐
相关产品推荐

