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

如何在djongo中查询关联外键的所有邮件组及用户信息

解决方案:获取包含关联用户的邮件组列表

问题回顾

我使用djongo作为MongoDB的数据库连接器,创建了MailGroup和User两个模型,每个User关联一个MailGroup,每个MailGroup可包含多个User。期望获取如下格式的嵌套数据:

mailGroups = [
    {
        "id": 1,
        "name": "group - 1",
        "users": [
            {
                "name": "x1",
                "email": "y1"
            },
            {
                "name": "x2",
                "email": "y2"
            }
        ]
    }
]

但当前执行以下代码仅能获取邮件组信息,无法拿到关联的用户:

mailGroups = MailGroup.objects.all()
serializer = MailGroupSerializer(mailGroups, many = True)

模型代码:

class MailGroup(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=255)

class User(models.Model):
    id = models.AutoField(primary_key=True)
    email = models.CharField(max_length=255)
    name = models.CharField(max_length=255)
    mailgroup = models.ForeignKey(MailGroup, on_delete=models.CASCADE)

序列化器代码:

class MailGroupSerializer(serializers.ModelSerializer):
    class Meta:
        model = MailGroup
        fields = ["id", "name"]

class RecipientSerializer(serializers.ModelSerializer):
    class Meta:
        model = Recipient
        fields = ["id", "email", "name", "mailGroup"]

解决步骤

1. 优化模型反向关联(可选但推荐)

在User模型的ForeignKey字段中指定related_name,让反向关联名称更直观:

class User(models.Model):
    id = models.AutoField(primary_key=True)
    email = models.CharField(max_length=255)
    name = models.CharField(max_length=255)
    # 指定反向关联名为users,方便后续调用
    mailgroup = models.ForeignKey(MailGroup, on_delete=models.CASCADE, related_name="users")

若不指定related_name,默认反向关联名称为user_set,后续步骤需对应替换。

2. 修改序列化器实现嵌套输出

创建仅包含用户姓名和邮箱的序列化器,再在MailGroupSerializer中嵌套该序列化器,关联到反向字段:

# 定义简化的用户序列化器,只返回需要的字段
class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ["name", "email"]

# 修改邮件组序列化器,嵌套用户序列化器
class MailGroupSerializer(serializers.ModelSerializer):
    # 关联反向字段users(未指定related_name则用user_set)
    users = UserSerializer(many=True, read_only=True)
    
    class Meta:
        model = MailGroup
        # 包含id、name和嵌套的users字段
        fields = ["id", "name", "users"]

注:原代码中RecipientSerializer对应模型应为User,此处统一修正为UserSerializer。

3. 优化查询避免N+1问题

使用prefetch_related预加载关联用户数据(djongo对MongoDB支持该操作):

# 预加载每个邮件组对应的用户
mailGroups = MailGroup.objects.all().prefetch_related("users")
serializer = MailGroupSerializer(mailGroups, many=True)
# serializer.data即为所需的嵌套格式数据

完整代码示例

模型文件

from django.db import models

class MailGroup(models.Model):
    id = models.AutoField(primary_key=True)
    name = models.CharField(max_length=255)

class User(models.Model):
    id = models.AutoField(primary_key=True)
    email = models.CharField(max_length=255)
    name = models.CharField(max_length=255)
    mailgroup = models.ForeignKey(MailGroup, on_delete=models.CASCADE, related_name="users")

序列化器文件

from rest_framework import serializers
from .models import MailGroup, User

class UserSerializer(serializers.ModelSerializer):
    class Meta:
        model = User
        fields = ["name", "email"]

class MailGroupSerializer(serializers.ModelSerializer):
    users = UserSerializer(many=True, read_only=True)
    
    class Meta:
        model = MailGroup
        fields = ["id", "name", "users"]

查询代码

from .models import MailGroup
from .serializers import MailGroupSerializer

def get_mail_groups():
    mailGroups = MailGroup.objects.all().prefetch_related("users")
    serializer = MailGroupSerializer(mailGroups, many=True)
    return serializer.data

内容的提问来源于stack exchange,提问作者user22168223

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 09:52:38