如何在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
相关产品推荐
相关产品推荐

