如何在Django现有视图中添加函数视图?路由注册报错求解
Django视图配置问题解答
问题描述
我当前的views.py代码如下,包含SentenceViewSet类视图,请问:
- 如何将
reverse_sentence函数添加为另一个视图? - 当我在
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
相关产品推荐
相关产品推荐

