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

使用drf-spectacular时出现QuerySet无model属性的AttributeError求助

解决drf-spectacular与rest_framework_mongoengine兼容的AttributeError问题

问题原因

drf-spectacular原本是为Django ORM设计的,它内部会依赖QuerySet的model属性生成API元数据,但rest_framework_mongoengine提供的QuerySet并没有这个属性,所以访问文档端点时会触发AttributeError: 'QuerySet' object has no attribute 'model'错误。

具体解决步骤

1. 自定义MongoEngine QuerySet转换器

创建转换器让drf-spectacular能识别mongoengine的QuerySet,在你的app下新建spectacular_extensions.py文件:

from drf_spectacular.plumbing import ResolvedComponent
from rest_framework_mongoengine.queryset import QuerySet
from drf_spectacular.settings import spectacular_settings

def mongoengine_queryset_converter(serializer, request, path, method):
    model_cls = serializer.Meta.model
    component = ResolvedComponent(
        name=f"{model_cls.__name__}List",
        type=ResolvedComponent.SERIALIZER,
        object=serializer,
        schema=None,
    )
    return {
        "type": "array",
        "items": component.ref,
    }

# 注册转换器到spectacular设置
spectacular_settings.SERIALIZER_CONVERTERS[QuerySet] = mongoengine_queryset_converter

然后在项目的settings.py里导入这个文件,确保它在drf-spectacular之前加载:

# settings.py
import your_app.spectacular_extensions

2. 显式定义视图的查询集和序列化器

不要依赖视图自动推断queryset,而是重写get_queryset方法,同时明确指定serializer_class:

from rest_framework_mongoengine.viewsets import ModelViewSet
from .models import Service
from .serializers import ServiceSerializer

class ServiceViewSet(ModelViewSet):
    serializer_class = ServiceSerializer
    
    def get_queryset(self):
        return Service.objects.all()

3. 用extend_schema显式声明视图的请求/响应格式

如果单个视图(比如你的CreateServiceAPI)还是有问题,用drf-spectacular的装饰器直接指定schema:

from rest_framework.generics import CreateAPIView
from drf_spectacular.utils import extend_schema
from .models import Service
from .serializers import ServiceSerializer

class CreateServiceAPI(CreateAPIView):
    serializer_class = ServiceSerializer
    
    @extend_schema(
        request=ServiceSerializer,
        responses=ServiceSerializer
    )
    def post(self, request, *args, **kwargs):
        return super().post(request, *args, **kwargs)

4. 调整spectacular配置避免自动检测冲突

在settings.py的SPECTACULAR_SETTINGS中,关闭可能引发问题的自动参数检测:

SPECTACULAR_SETTINGS = {
    'TITLE': '你的API名称',
    'DESCRIPTION': '基于Django-MongoEngine的API文档',
    'VERSION': '1.0.0',
    'AUTO_INCLUDE_PARAMETERS': False,
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 21:05:32