You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 02:32:50