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

DRF中使用.as_view({'post': 'list'})出现AttributeError问题求助

问题描述

尝试向DRF端点发送文本(例如:"Hello World"),该端点需接收文本后发送包含此文本的邮件。使用Postman请求该端点时,触发以下错误:

Internal Server Error: /api/errors
Traceback (most recent call last):
File "/Users/sid/eb-virt/lib/python3.8/site-packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
File "/Users/sid/eb-virt/lib/python3.8/site-packages/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/sid/eb-virt/lib/python3.8/site-packages/django/views/decorators/csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
File "/Users/sid/eb-virt/lib/python3.8/site-packages/rest_framework/viewsets.py", line 117, in view
handler = getattr(self, action)
AttributeError: 'ErrorMsgViewSet' object has no attribute 'list'

相关代码

urls.py

from django.urls import path
from .api import *

urlpatterns = [
    path('api/errors', ErrorMsgViewSet.as_view({'post': 'list'}), name='errors'),
]

# 我尝试过使用.as_view(),但报错要求改为上述格式
# 尝试使用router.register()结合generic.GenericAPIview时也出现错误

api.py

from rest_framework import viewsets
from email_alerts.serializers import ErrorsSerializer


class ErrorMsgViewSet(viewsets.GenericViewSet):
    serializer_class = ErrorsSerializer
    permission_classes = [
        
    ]

    def post(self, request, *args, **kwargs):
        print(request.data)

models.py

from django.db import models


# Create your models here.
class ErrorsModel(models.Model):
    error_msg = models.CharField(max_length=5000, blank=True, null=True)

serializers.py

from rest_framework import serializers
from email_alerts.models import ErrorsModel


class ErrorsSerializer(serializers.ModelSerializer):
    error_msg = serializers.CharField(
        required=False, allow_null=True, allow_blank=True)

    class Meta:
        model = ErrorsModel
        fields = '__all__'
解决方案

错误根源是URL配置与视图集方法的映射不匹配:

  1. 你在urls.py中将POST请求映射到了list方法,但ErrorMsgViewSet并未定义该方法,反而自定义了post方法,二者完全不对应。
  2. DRF视图集的规范是用动作名称映射请求方法,比如create对应POST请求,而非直接使用post方法名。

修改方案一(遵循视图集规范)

  • 修改api.py:将自定义的post方法重命名为create,并补充业务逻辑(保存数据、发送邮件):
from rest_framework import viewsets, status
from rest_framework.response import Response
from email_alerts.serializers import ErrorsSerializer
from django.core.mail import send_mail

class ErrorMsgViewSet(viewsets.GenericViewSet):
    serializer_class = ErrorsSerializer
    permission_classes = []

    def create(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        # 可选:保存数据到数据库
        serializer.save()
        # 发送邮件
        error_msg = serializer.validated_data.get('error_msg')
        send_mail(
            '错误通知',
            error_msg,
            '你的发件邮箱@example.com',
            ['收件邮箱@example.com'],
            fail_silently=False,
        )
        return Response(serializer.data, status=status.HTTP_201_CREATED)
  • 修改urls.py:将POST请求正确映射到create动作:
from django.urls import path
from .api import ErrorMsgViewSet

urlpatterns = [
    path('api/errors', ErrorMsgViewSet.as_view({'post': 'create'}), name='errors'),
]

修改方案二(使用APIView简化)

如果不想遵循视图集动作规范,可直接改用APIView,支持直接定义post方法:

  • 修改api.py:
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import status
from email_alerts.serializers import ErrorsSerializer
from django.core.mail import send_mail

class ErrorMsgAPIView(APIView):
    permission_classes = []

    def post(self, request, *args, **kwargs):
        serializer = ErrorsSerializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        # 保存数据+发送邮件逻辑同上
        error_msg = serializer.validated_data.get('error_msg')
        send_mail(
            '错误通知',
            error_msg,
            '你的发件邮箱@example.com',
            ['收件邮箱@example.com'],
            fail_silently=False,
        )
        return Response(serializer.data, status=status.HTTP_201_CREATED)
  • 修改urls.py:
from django.urls import path
from .api import ErrorMsgAPIView

urlpatterns = [
    path('api/errors', ErrorMsgAPIView.as_view(), name='errors'),
]

完成修改后,用Postman发送POST请求到/api/errors,携带包含error_msg字段的JSON数据,即可正常触发邮件发送逻辑,不会再出现属性错误。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 09:05:39