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

如何在Django现有视图中添加函数视图?路由注册报错求解

Django视图配置问题解答

问题描述

我当前的views.py代码如下,包含SentenceViewSet类视图,请问:

  1. 如何将reverse_sentence函数添加为另一个视图?
  2. 当我在urls.py中使用router.register(r'reverse_sentence', views.reverse_sentence, basename='reverse_sentence')注册时,出现AttributeError: 'function' object has no attribute 'get_extra_actions'错误,原因是什么?

代码片段:

class SentenceViewSet(viewsets.ModelViewSet):
    queryset = Sentence.objects.all()
    serializer_class = SentenceSerializer


def reverse_sentence(request):
    if request.method == 'POST':
        sentence = Sentence.objects.all.values('content')
        reversed_words = ' '.join(reversed(sentence.split()))
        response_data = {'reversed_sentence': reversed_words}
        return JsonResponse(response_data)
    else:
        return JsonResponse({'error': 'Invalid request method. Must use POST.'})

问题解答

1. 配置reverse_sentence视图的两种方式

方式一:直接映射函数视图

不需要用DRF的路由注册器(router),直接在urls.py里用path绑定:

from django.urls import path
import views

urlpatterns = [
    # 其他已有路由
    path('reverse_sentence/', views.reverse_sentence, name='reverse_sentence'),
]

注意:原函数里有个逻辑错误——Sentence.objects.all.values('content')返回的是QuerySet对象,不能直接调用split(),得改成具体取某条数据的content,比如取第一条:

def reverse_sentence(request):
    if request.method == 'POST':
        sentence_obj = Sentence.objects.first()
        if not sentence_obj:
            return JsonResponse({'error': 'No sentences found'}, status=404)
        reversed_words = ' '.join(reversed(sentence_obj.content.split()))
        return JsonResponse({'reversed_sentence': reversed_words})
    else:
        return JsonResponse({'error': 'Invalid request method. Must use POST.'}, status=405)

方式二:转为类视图(适配DRF router)

如果想统一用DRF的类视图风格,可以把函数包装成APIView子类,这样就能用router注册了:
修改views.py:

from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status

class ReverseSentenceView(APIView):
    def post(self, request):
        sentence_obj = Sentence.objects.first()
        if not sentence_obj:
            return Response({'error': 'No sentences found'}, status=status.HTTP_404_NOT_FOUND)
        reversed_words = ' '.join(reversed(sentence_obj.content.split()))
        return Response({'reversed_sentence': reversed_words})
    
    def get(self, request):
        return Response(
            {'error': 'Invalid request method. Must use POST.'}, 
            status=status.HTTP_405_METHOD_NOT_ALLOWED
        )

然后在urls.py里用router注册:

router.register(r'reverse_sentence', views.ReverseSentenceView, basename='reverse_sentence')

或者用path映射:

path('reverse_sentence/', views.ReverseSentenceView.as_view(), name='reverse_sentence'),

2. 报错原因

DRF的router.register()只能用来注册DRF视图集(ViewSet)的子类,比如你已有的SentenceViewSet。普通函数视图没有ViewSet类的get_extra_actions()方法,router调用这个方法时自然会抛出属性错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 02:33:19