如何在Django序列化器中获取登录用户与上下文用户的互发邮件?
问题原因
核心问题是字段名称冲突:
- 你在
Mail模型中给sender设置了related_name="mail_sent",给receiver设置了related_name="mail_received",这两个名称和UserSerializer里自定义的mail_sent、mail_received这两个SerializerMethodField完全重名。 - 加上
Meta类里设置了depth=1,DRF会自动序列化模型的关联字段,这就和你自定义的方法字段产生冲突,导致自定义的邮件过滤逻辑无法生效,最终返回空数组;单独保留其中一个字段时,冲突消失,自定义逻辑就能正常执行。
解决方法
有两种可行方案,任选其一即可:
方案一:重命名自定义字段,避免冲突
修改UserSerializer里的自定义字段名称,同时更新对应的方法名和fields列表:
class UserSerializer(serializers.ModelSerializer): is_connected = serializers.SerializerMethodField() sent_to_current_user = serializers.SerializerMethodField() received_from_current_user = serializers.SerializerMethodField() class Meta: model = User fields = [ "id", "username", "role", "upgraded", "verified", "email", "settings", "is_connected", "sent_to_current_user", "received_from_current_user", ] depth = 1 def get_is_connected(self, user): request = self.context.get("request") if request and request.user.is_authenticated: logged_in_user = request.user is_connected = ( Connection.objects.filter( Q(userone=user, usertwo=logged_in_user) | Q(userone=logged_in_user, usertwo=user) ).exists() ) return is_connected return False def get_sent_to_current_user(self, user): request = self.context.get("request") if request and request.user.is_authenticated: logged_in_user = request.user mail_sent = user.mail_sent.filter(receiver=logged_in_user) serializer = MailSerializer(mail_sent, many=True) return serializer.data return [] def get_received_from_current_user(self, user): request = self.context.get("request") if request and request.user.is_authenticated: logged_in_user = request.user mail_received = user.mail_received.filter(sender=logged_in_user) serializer = MailSerializer(mail_received, many=True) return serializer.data return []
方案二:移除depth=1,禁用自动关联序列化
如果不想修改字段名称,直接删除Meta类里的depth=1配置,这样DRF不会自动序列化模型的关联字段,自定义的SerializerMethodField就能正常生效:
class UserSerializer(serializers.ModelSerializer): is_connected = serializers.SerializerMethodField() mail_sent = serializers.SerializerMethodField() mail_received = serializers.SerializerMethodField() class Meta: model = User fields = [ "id", "username", "role", "upgraded", "verified", "email", "settings", "is_connected", "mail_sent", "mail_received", ] # 移除 depth = 1 配置 def get_is_connected(self, user): request = self.context.get("request") if request and request.user.is_authenticated: logged_in_user = request.user is_connected = ( Connection.objects.filter( Q(userone=user, usertwo=logged_in_user) | Q(userone=logged_in_user, usertwo=user) ).exists() ) return is_connected return False def get_mail_sent(self, user): request = self.context.get("request") if request and request.user.is_authenticated: logged_in_user = request.user mail_sent = user.mail_sent.filter(receiver=logged_in_user) serializer = MailSerializer(mail_sent, many=True) return serializer.data return [] def get_mail_received(self, user): request = self.context.get("request") if request and request.user.is_authenticated: logged_in_user = request.user mail_received = user.mail_received.filter(sender=logged_in_user) serializer = MailSerializer(mail_received, many=True) return serializer.data return []
验证效果
两种方案都能确保:
- 仅返回当前上下文用户与登录用户之间的邮件
- 自定义的邮件过滤逻辑正常执行,不会被自动序列化的字段覆盖
内容的提问来源于stack exchange,提问作者crawlingdev
相关产品推荐
相关产品推荐

