如何完全关闭Django REST Framework的URL渲染,使访问API路由时返回404页面?
解决方案:让DRF列表URL返回404或无内容
要实现你想要的效果——让localhost:8000/products返回404甚至无内容,仅仅修改渲染器是不够的,因为DRF的Simple Router依然会生成列表视图的路由,匹配请求后返回JSON数据。下面是几种针对性的解决方案:
方案1:自定义Router,移除列表视图路由
如果你希望全局(或多个ViewSet)都禁用列表URL,可以继承SimpleRouter并过滤掉列表相关的路由规则:
from rest_framework.routers import SimpleRouter class NoListRouter(SimpleRouter): def get_urls(self): # 获取默认生成的所有路由 urls = super().get_urls() # 过滤掉名称包含"-list"的路由(DRF默认列表路由的name格式为"{prefix}-list") filtered_urls = [url for url in urls if '-list' not in url.name] return filtered_urls
然后在你的urls.py中使用这个自定义Router代替原生的SimpleRouter:
from .routers import NoListRouter from .views import ProductViewSet router = NoListRouter() router.register(r'products', ProductViewSet) urlpatterns = router.urls
这样/products就不会被DRF的路由匹配,访问时会返回Django默认的404页面。
方案2:在ViewSet中重写list方法,直接返回404/无内容
如果你只需要针对单个ViewSet禁用列表功能,可以在视图集中重写list方法,主动返回404或者无内容响应:
返回404示例:
from rest_framework import viewsets from django.http import Http404 from .models import Product from .serializers import ProductSerializer class ProductViewSet(viewsets.ModelViewSet): queryset = Product.objects.all() serializer_class = ProductSerializer def list(self, request, *args, **kwargs): # 直接抛出404异常,触发Django的404页面 raise Http404("Page not found")
返回无内容(204状态码)示例:
from rest_framework import viewsets from django.http import HttpResponse from .models import Product from .serializers import ProductSerializer class ProductViewSet(viewsets.ModelViewSet): queryset = Product.objects.all() serializer_class = ProductSerializer def list(self, request, *args, **kwargs): # 返回无内容的响应,浏览器不会显示任何内容 return HttpResponse(status=204)
方案3:手动编写路由,只注册详情页URL
如果你不需要使用Router自动生成路由,可以手动在urls.py中只配置详情页的URL,完全不注册列表路由:
from django.urls import path from .views import ProductViewSet # 只注册详情页的视图(绑定retrieve动作) product_detail = ProductViewSet.as_view({'get': 'retrieve'}) urlpatterns = [ path('products/<int:pk>/', product_detail, name='product-detail'), ]
这种方式最直接,/products因为没有对应的路由规则,会直接返回404页面。
内容的提问来源于stack exchange,提问作者user655941
相关产品推荐
相关产品推荐

