如何在无attrs参数的方法中访问DRF序列化器的字段属性
你报错的核心原因是:self.participants 指向的是序列化器定义的字段对象,既不是Conversation模型实例的关联属性,也不是序列化后的participants数据列表。SerializerMethodField对应的方法会自动传入当前正在序列化的模型实例obj,你只需要把这个参数透传给get_other_user即可。
修改后的完整代码
class ConversationSerializer(serializers.ModelSerializer): other_username = serializers.SerializerMethodField(method_name='get_other_username', read_only=True) other_user_email = serializers.SerializerMethodField(method_name='get_other_user_email', read_only=True) participants = UsersSerializer(many=True, read_only=True) class Meta: model = Conversation fields = ['conversation_id' ,'participants','other_username', 'other_user_email'] def get_current_user_id(self): return self.context['current_user'].id def get_other_user(self, obj): # 缓存结果,避免多次调用重复遍历 if hasattr(self, '_cached_other_user'): return self._cached_other_user current_user_id = self.get_current_user_id() # 直接从Conversation模型实例读取participants关联数据 for participant in obj.participants.all(): if participant.id != current_user_id: self._cached_other_user = participant return participant def get_other_username(self, obj): other_user = self.get_other_user(obj) return other_user.username def get_other_user_email(self, obj): other_user = self.get_other_user(obj) return other_user.email
如果你需要读取序列化后的participants字典数据,可使用以下版本的get_other_user方法:
def get_other_user(self, obj): if hasattr(self, '_cached_other_user'): return self._cached_other_user current_user_id = self.get_current_user_id() # 主动调用participants字段的序列化方法得到字典列表 serialized_participants = self.fields['participants'].to_representation(obj.participants.all()) for participant in serialized_participants: if participant['id'] != current_user_id: self._cached_other_user = participant return participant
对应修改属性读取方式为字典取值即可:
def get_other_username(self, obj): other_user = self.get_other_user(obj) return other_user['username'] def get_other_user_email(self, obj): other_user = self.get_other_user(obj) return other_user['email']
内容的提问来源于stack exchange,提问作者Arkash Vijayakumar
相关产品推荐
相关产品推荐

