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

Django REST Framework函数视图GET/PUT/DELETE接口失效排查

排查city_detail视图无法运行的问题

以下是几个关键问题点,按优先级排序:

1. 权限类方法缩进错误

在permissions.py中,has_object_permission方法的缩进不正确,它当前是全局函数,而非IsOwnerOrReadOnly类的成员方法。这会导致DRF无法识别权限判断逻辑,直接触发权限验证失败。

修复后的代码:

from rest_framework import permissions

class IsOwnerOrReadOnly(permissions.BasePermission):
    """
    Custom permission to only allow owners of an object to edit it.
    """
    # 修正缩进,使方法属于类成员
    def has_object_permission(self, request, view, obj):
        # Read permissions are allowed to any request,
        # So we'll always allow GET, HEAD or OPTIONS requests.
        if request.method in permissions.SAFE_METHODS:
            return True
        
        # Write permissions are only allowed to the owner of the city.
        return obj.owner == request.user

2. 装饰器顺序错误

city_detail视图的装饰器顺序颠倒,DRF要求@api_view必须放在@permission_classes前面。因为@api_view会为函数视图注入DRF核心处理逻辑,@permission_classes依赖该逻辑才能正常工作。

修复后的视图装饰器:

@api_view(['GET', 'PUT', 'DELETE'])
@permission_classes([IsAuthenticated, IsOwnerOrReadOnly])
def city_detail(request, pk, format=None):
    # ... 原有代码 ...

3. 使用Django原生响应替代DRF Response

city_detail中使用了JsonResponse和HttpResponse,而非DRF提供的Response类,这会导致:

  • DRF的内容协商(格式后缀、Accept头)失效
  • 权限验证后的错误信息无法正确格式化
  • 无法利用DRF的异常处理机制

修复后的响应代码:

from rest_framework.response import Response
# ... 其他必要导入 ...

def city_detail(request, pk, format=None):
    """
    Retrieve, update or delete a city.
    """
    try:
        city = City.objects.get(pk=pk)
    except City.DoesNotExist:
        return Response(status=status.HTTP_404_NOT_FOUND)

    if request.method == 'GET':
        serializer = CitySerializer(city)
        return Response(serializer.data)

    elif request.method == 'PUT':
        serializer = CitySerializer(city, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    elif request.method == 'DELETE':
        city.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

4. 冗余的URL配置

app.urls.py中存在path('cities/create/', views.city_create),但city_list已支持POST方法创建城市,该路由属于冗余配置,可能导致路由冲突或逻辑混淆。若未实现city_create视图,访问该URL还会触发视图不存在的错误,建议删除该路由。

额外小问题

  • city_detail的文档字符串描述为"Retrieve, update or delete a code snippet.",应改为对应城市的描述(如"Retrieve, update or delete a city."),提升代码可维护性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 16:52:53