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

Django抽象模型无法实例化求助:使用djongo ArrayField报错

问题:使用抽象模型作为djongo ArrayField容器时实例化错误

创建了MailGroup和Recipient两个模型,将Recipient的abstract属性设为True。当执行mailGroups = MailGroup.objects.all()获取MailGroup对象列表时,抛出如下错误:

TypeError: Abstract models cannot be instantiated.

涉及代码文件

models.py

from djongo import models

class Recipient(models.Model):
    recipientName = models.CharField(max_length=255, null = False)
    recipientMailId = models.EmailField(max_length = 255, unique = True, null = False)

    class Meta:
        abstract = True


class MailGroup(models.Model):
    mailGroupName = models.CharField(max_length = 255, unique = True, null = False)
    recipients = models.ArrayField(
        model_container = Recipient
    )

    class Meta:
        abstract = False

serializers.py

from rest_framework import serializers
from dashboardServer.models import MailGroup

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

views.py

@api_view(["GET", "POST", "PATCH", "DELETE"])
def mailGroupsView(request):

    if request.method == "GET":
        mailGroups = MailGroup.objects.all() # 此处抛出上述错误
        serializer = MailGroupSerializer(mailGroups, many = True)
        return JsonResponse({
            "status": "success",
            "info": "Mail groups fetched successfully",
            "title": "Success",
            "data": serializer.data
        }, status = 200)

当前使用版本:Django 4.1.9、sqlparse 0.2.4、djongo 1.3.6

解决方案

错误核心原因:Django禁止实例化抽象模型,而djongo在处理ArrayField的model_container参数时,会尝试创建对应模型的实例来封装数据库读取的嵌套数据,因此使用抽象模型Recipient会触发报错。

方法一:将Recipient改为非抽象模型(推荐)

移除Recipient模型中的abstract = True,同时设置managed = False避免Django为其创建单独的MongoDB集合:

class Recipient(models.Model):
    recipientName = models.CharField(max_length=255, null=False)
    recipientMailId = models.EmailField(max_length=255, unique=True, null=False)

    class Meta:
        managed = False  # 不生成单独集合,仅作为嵌套文档的模型定义

方法二:改用DictField配合自定义序列化验证

如果不想用模型定义嵌套结构,可将MailGroup的recipients改为DictField,再在序列化器中手动定义字段验证规则:

  1. 修改models.py:
class MailGroup(models.Model):
    mailGroupName = models.CharField(max_length=255, unique=True, null=False)
    recipients = models.ArrayField(
        model_container=models.DictField()
    )
  1. 修改serializers.py,添加嵌套序列化器:
from rest_framework import serializers
from dashboardServer.models import MailGroup

class RecipientSerializer(serializers.Serializer):
    recipientName = serializers.CharField(max_length=255, required=True)
    recipientMailId = serializers.EmailField(max_length=255, required=True)

class MailGroupSerializer(serializers.ModelSerializer):
    recipients = RecipientSerializer(many=True)
    class Meta:
        model = MailGroup
        fields = ["id", "mailGroupName", "recipients"]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 14:12:55