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

使用Django REST Framework构建函数式API时遭遇AssertionError及相关权限类、渲染器错误

解决你的Django REST Framework函数式API错误

嘿,我来帮你搞定这两个接连出现的问题!咱们一个个拆解来看:

第一个错误:Cannot apply DjangoModelPermissionsOrAnonReadOnly on a view that does not set .queryset or have a .get_queryset()

这个报错的核心原因很明确:你用的DjangoModelPermissionsOrAnonReadOnly权限类是为类视图设计的,它要求视图必须暴露queryset属性或者实现get_queryset()方法,这样权限系统才能判断用户对模型的操作权限。但你的函数视图里只是在内部定义了queryset变量,DRF的权限系统根本识别不到它。

有两种简单的解决办法:

方法1:给函数视图手动添加queryset属性

直接在函数外面补上这一行,让权限系统能找到对应的模型查询集:

@api_view(('GET',))
@renderer_classes((TemplateHTMLRenderer, JSONRenderer))
def course_api(request):
    if request.method == 'GET':
        queryset = Course.objects.all()
        serializer = CourseNameSerializers(queryset, many=True)
        return Response(serializer.data, template_name='api.html')

# 手动添加queryset属性,让权限系统识别
course_api.queryset = Course.objects.all()

方法2:更换更适合函数视图的权限类

如果你不需要严格的模型级权限控制,直接换成IsAuthenticatedOrReadOnly或者AllowAny这类轻量化权限类就行。用@permission_classes装饰器指定即可:

from rest_framework.permissions import IsAuthenticatedOrReadOnly

@api_view(('GET',))
@permission_classes([IsAuthenticatedOrReadOnly])  # 添加权限类装饰器
@renderer_classes((TemplateHTMLRenderer, JSONRenderer))
def course_api(request):
    if request.method == 'GET':
        queryset = Course.objects.all()
        serializer = CourseNameSerializers(queryset, many=True)
        return Response(serializer.data, template_name='api.html')

第二个错误:.accepted_renderer not set on Response

这个错误完全是因为你去掉了@api_view装饰器!DRF的Response对象依赖api_view装饰器完成一系列初始化工作:比如根据请求头选择合适的渲染器、设置accepted_renderer属性等。没有这个装饰器,Response根本不知道该怎么处理返回的数据,自然就报错了。

所以绝对不能去掉@api_view装饰器,它是函数视图能正常工作的核心。

把两个问题的解决方案结合起来,最终可运行的代码示例(以方法2为例)如下:

from rest_framework.decorators import api_view, renderer_classes, permission_classes
from rest_framework.permissions import IsAuthenticatedOrReadOnly
from rest_framework.renderers import TemplateHTMLRenderer, JSONRenderer
from rest_framework.response import Response
from .models import Course
from .serializers import CourseNameSerializers

@api_view(('GET',))
@permission_classes([IsAuthenticatedOrReadOnly])
@renderer_classes((TemplateHTMLRenderer, JSONRenderer))
def course_api(request):
    if request.method == 'GET':
        queryset = Course.objects.all()
        serializer = CourseNameSerializers(queryset, many=True)
        return Response(serializer.data, template_name='api.html')

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.30 16:02:48