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

Django REST如何编写测试用例验证方法不被允许?

我来帮你搞定这个测试用例的问题!首先咱们得明确:你的OrderViewSet只继承了CreateModelMixin和GenericViewSet,也就是说只有**创建(POST)**接口是开放的,其他四个操作——列表查询、详情获取、部分更新、删除都应该返回405 Method Not Allowed状态码。下面是完整的测试实现,同时解决你提到的reverse()使用问题。

核心思路

  1. 利用Django REST Framework的APITestCase来编写测试,它能方便地模拟HTTP请求
  2. 通过reverse()生成正确的接口URL(关键是要匹配Router自动生成的URL名称)
  3. 对每个被禁用的操作发送对应请求,断言返回状态码为405

完整测试代码

from django.urls import reverse
from rest_framework.test import APITestCase
from rest_framework import status
from .models import Order  # 导入你的Order模型
from .serializers import OrderSerializer  # 导入你的序列化器

class OrderViewSetPermissionTests(APITestCase):
    def setUp(self):
        # 预先创建一个测试订单,用于详情、更新、删除测试
        self.test_order = Order.objects.create(
            # 这里填写你的Order模型所需的字段,示例如下
            total_amount=199.99,
            status="pending",
            customer_name="Test User"
        )

    def test_list_orders_is_not_allowed(self):
        """测试列表查询(GET /orders/)不被允许"""
        # 生成列表接口的URL,名称由Router自动生成(前缀为orders时,名称是order-list)
        url = reverse("order-list")
        response = self.client.get(url)
        self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)

    def test_retrieve_order_is_not_allowed(self):
        """测试详情获取(GET /orders/<pk>/)不被允许"""
        url = reverse("order-detail", kwargs={"pk": self.test_order.pk})
        response = self.client.get(url)
        self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)

    def test_partial_update_order_is_not_allowed(self):
        """测试部分更新(PATCH /orders/<pk>/)不被允许"""
        url = reverse("order-detail", kwargs={"pk": self.test_order.pk})
        update_data = {"status": "completed"}
        response = self.client.patch(url, update_data, format="json")
        self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)

    def test_delete_order_is_not_allowed(self):
        """测试删除操作(DELETE /orders/<pk>/)不被允许"""
        url = reverse("order-detail", kwargs={"pk": self.test_order.pk})
        response = self.client.delete(url)
        self.assertEqual(response.status_code, status.HTTP_405_METHOD_NOT_ALLOWED)

解决reverse()的使用问题

你之前用reverse()出错,大概率是没匹配到正确的URL名称。Django REST Framework的Router会根据你注册的ViewSet自动生成URL名称:

  • 如果你是这样注册的:router.register(r'orders', OrderViewSet)
  • 那么列表接口的名称是order-list,详情接口的名称是order-detail

不确定的话,可以直接运行以下命令查看所有注册的URL及对应名称:

python manage.py show_urls

额外注意事项

确保你的OrderViewSet配置了基础的queryset和serializer_class,否则可能会出现其他错误(虽然不影响405的断言,但规范配置能避免不必要的问题):

from rest_framework import viewsets, mixins
from .models import Order
from .serializers import OrderSerializer

class OrderViewSet(mixins.CreateModelMixin, viewsets.GenericViewSet):
    queryset = Order.objects.all()
    serializer_class = OrderSerializer

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:22:04