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

在Django REST Framework中通过ID获取IssueReport模型数据报错求助

Django REST Framework 通过ID获取IssueReport数据的问题排查与解决

问题描述

我想在Django REST Framework中通过ID获取IssueReport模型的数据,于是用POST方法手动传递ID来获取对应数据,但遇到两个问题:

  1. 发送GET请求到接口时提示Method Not Allowed
  2. 发送POST请求时触发IssueReport.DoesNotExist异常

报错信息

Method Not Allowed: /app/auth/getissuereport/
[10/Aug/2022 23:26:21] "GET /app/auth/getissuereport/ HTTP/1.1" 405 7036
Internal Server Error: /app/auth/getissuereport/
Traceback (most recent call last):
  File "D:\MMRDA\.venv\lib\site-packages\django\core\handlers\exception.py", line 55, in inner
    response = get_response(request)
  File "D:\MMRDA\.venv\lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "D:\MMRDA\.venv\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "D:\MMRDA\.venv\lib\site-packages\django\views\generic\base.py", line 84, in view
    return self.dispatch(request, *args, **kwargs)
  File "D:\MMRDA\.venv\lib\site-packages\rest_framework\views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "D:\MMRDA\.venv\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "D:\MMRDA\.venv\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
    raise exc
  File "D:\MMRDA\.venv\lib\site-packages\rest_framework\views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "D:\MMRDA\mmrda\apis\views.py", line 195, in post
    report=IssueReport.objects.get(pk=id)
  File "D:\MMRDA\.venv\lib\site-packages\django\db\models\manager.py", line 85, in manager_method
    return getattr(self.get_queryset(), name)(*args, **kwargs)
  File "D:\MMRDA\.venv\lib\site-packages\django\db\models\query.py", line 496, in get
    raise self.model.DoesNotExist(
DataSet.models.IssueReport.DoesNotExist: IssueReport matching query does not exist.

现有代码

views.py

class GetIssueReportById(generics.GenericAPIView):

    serializer_class=GetIssueReportSerializer
    def post(self,request,*args,**kwargs):
        serializer=self.get_serializer(data=request.data)
        if serializer.is_valid(raise_exception=True):
            id=serializer.data.get('id')
            report=IssueReport.objects.get(pk=id)
            data=IssueReportSerializer(report,context=self.get_serializer_context()).data
            return Response({
                'message':"Data Fetched successfully",
                'status':"success",
                'data':data,
                },status=status.HTTP_200_OK)
        else:
            return Response({
                'message':"Data not fetched",
                'status':status.HTTP_400_BAD_REQUEST
                })

serializers.py

class IssueReportSerializer(serializers.ModelSerializer):
    class Meta:
        model=IssueReport
        fields='__all__'

class GetIssueReportSerializer(serializers.ModelSerializer):
    class Meta:
        model=IssueReport
        fields=('id',)

问题解决与优化

1. 解决Method Not Allowed(GET请求不被允许)

你的视图只实现了post方法,因此默认不处理GET请求。有两种处理方案:

方案一:添加GET方法支持

如果需要通过GET请求传ID(比如查询参数?id=1),可以在视图中添加get方法:

def get(self, request, *args, **kwargs):
    report_id = request.query_params.get('id')
    if not report_id:
        return Response({
            'message': "缺少id参数",
            'status': "error"
        }, status=status.HTTP_400_BAD_REQUEST)
    # 用get_object_or_404替代get,避免异常
    report = get_object_or_404(IssueReport, pk=report_id)
    data = IssueReportSerializer(report, context=self.get_serializer_context()).data
    return Response({
        'message': "数据获取成功",
        'status': "success",
        'data': data,
    }, status=status.HTTP_200_OK)

方案二:遵循RESTful规范(推荐)

获取单条资源的标准做法是用GET请求+URL路径参数,DRF提供了RetrieveAPIView可以直接实现这个逻辑,无需手动编写查询和序列化代码:

from django.shortcuts import get_object_or_404
from rest_framework import generics
from .models import IssueReport
from .serializers import IssueReportSerializer

class GetIssueReportById(generics.RetrieveAPIView):
    queryset = IssueReport.objects.all()
    serializer_class = IssueReportSerializer
    # lookup_field默认是'id',可以省略
    # lookup_field = 'id'

使用时直接请求/app/auth/getissuereport/1/(1为目标ID)即可自动返回对应数据,同时自动处理404(ID不存在时)和请求方法校验。


2. 解决POST请求触发DoesNotExist异常

这个异常的核心原因是传入的ID在数据库中不存在,或者参数传递有误。可以从以下几点优化:

  • 校验ID存在性:用get_object_or_404替代IssueReport.objects.get(),这样查询不到时会自动返回404响应,而不是抛出未捕获的异常
  • 检查参数传递:确保POST请求的Body是正确的JSON格式,比如{"id": 1},且ID确实存在于数据库中
  • 使用validated_data:从serializer.validated_data.get('id')获取ID,比serializer.data.get('id')更可靠,因为validated_data是经过验证后的数据

优化后的POST视图代码:

from django.shortcuts import get_object_or_404

class GetIssueReportById(generics.GenericAPIView):
    serializer_class = GetIssueReportSerializer

    def post(self, request, *args, **kwargs):
        serializer = self.get_serializer(data=request.data)
        serializer.is_valid(raise_exception=True)
        # 从validated_data取ID
        report_id = serializer.validated_data.get('id')
        # 自动处理不存在的情况
        report = get_object_or_404(IssueReport, pk=report_id)
        data = IssueReportSerializer(report, context=self.get_serializer_context()).data
        return Response({
            'message': "数据获取成功",
            'status': "success",
            'data': data,
        }, status=status.HTTP_200_OK)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.23 00:54:29