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,再在序列化器中手动定义字段验证规则:
- 修改models.py:
class MailGroup(models.Model): mailGroupName = models.CharField(max_length=255, unique=True, null=False) recipients = models.ArrayField( model_container=models.DictField() )
- 修改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
相关产品推荐
相关产品推荐

