Python新手求助:将Django项目URL迁移至DRF Router并生成API路由列表
Hey there! Let's break down how to get that REST API route list working for your Django project. The key thing to note here is that Django REST Framework's DefaultRouter only automatically generates route lists for ViewSet classes, not the traditional function-based views you're currently using in api.v2.urls and helps.urls. Here are two approaches to fix this:
方案1:改造现有视图为ViewSet(推荐)
This is the cleanest long-term solution because it leverages DRF's built-in tools for routing, documentation, and API consistency. Here's how to adapt your existing code:
步骤1:将函数视图转换为ViewSet
Open api/v2/views.py and wrap your existing functions into a ViewSet class, using DRF's @action decorator to match your original URL paths:
from rest_framework import viewsets, status from rest_framework.decorators import action from rest_framework.response import Response class APIV2ViewSet(viewsets.ViewSet): # Match /api/v2/data/info @action(detail=False, methods=['get'], url_path='data/info') def info_data(self, request): # Copy your original info_data function logic here return Response({"message": "Info data response"}, status=status.HTTP_200_OK) # Match /api/v2/visits @action(detail=False, methods=['get']) def visits(self, request): # Copy your original visits function logic here return Response({"visits": 42}, status=status.HTTP_200_OK) # Match /api/v2/additional_info/ @action(detail=False, methods=['get']) def additional_info(self, request): # Copy your original additional_info function logic here return Response({"extra": "Additional info"}, status=status.HTTP_200_OK)
Repeat this pattern for your helps/views.py functions to create a HelpsViewSet.
步骤2:更新URL配置以使用Router
Modify api/v2/urls.py to use a router instead of manual url() entries:
# -*- coding: utf-8 -*- from django.conf.urls import include from rest_framework import routers from api.v2.views import APIV2ViewSet router = routers.DefaultRouter() router.register(r'', APIV2ViewSet, basename='api-v2') urlpatterns = [ include(router.urls) ]
Then adjust your root urls.py to fix the router path conflict (your current r'^' router entry gets overridden by the home view). Change it to ensure the router's root view is accessible:
# -*- coding: utf-8 -*- import re from django.conf import settings from django.conf.urls import include, url from django.contrib import admin from django.views.static import serve from rest_framework import routers import home.views # Import your new ViewSets from api.v2.views import APIV2ViewSet from helps.views import HelpsViewSet router = routers.DefaultRouter() # Register your ViewSets with the router router.register(r'api/v2', APIV2ViewSet, basename='api-v2') router.register(r'help', HelpsViewSet, basename='helps') urlpatterns = [ url(r'^$', home.views.HomeView.as_view()), # Remove the old manual includes for api/v2 and help # url(r'^api/v2/', include('api.v2.urls', namespace='api-v2')), # url(r'^help/', include('helps.urls', namespace='helps')), url(r'^admin/', include(admin.site.urls)), url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')), url(r'^', include(router.urls)) ]
步骤3:查看路由列表
Now if you run your server and visit http://localhost:8000/api/v2/ (or the base path of your registered ViewSets), you'll see a browsable API page with all your API routes listed neatly.
方案2:不改造视图,手动添加到DRF可浏览API
If you don't want to rewrite all your views right now, you can still make them visible in DRF's browsable API (though you won't get an automatic unified route list). Here's how:
步骤1:装饰函数视图
Add the @api_view decorator to your functions in api/v2/views.py:
from rest_framework.decorators import api_view from rest_framework.response import Response @api_view(['GET']) def info_data(request): # Original logic here return Response({"message": "Info data"}) @api_view(['GET']) def visits(request): # Original logic here return Response({"visits": 42}) @api_view(['GET']) def additional_info(request): # Original logic here return Response({"extra": "Info"})
步骤2:访问单个端点
Each API endpoint will now show up in DRF's browsable interface when you visit it directly (e.g., http://localhost:8000/api/v2/visits), but you won't get a single page with all routes listed. For that, you'd need to build a custom view to scan your URL patterns, which is more work than just using ViewSets.
关键注意事项
- URL Order Matters: Make sure your router's
includeentry doesn't get overridden by earlier URL patterns (like your home view). Using explicit prefixes for router registrations avoids this. - Namespace Compatibility: If you need to keep namespaces, you can pass the
namespaceargument toinclude()when adding router URLs, but ViewSets work best with thebasenameparameter during router registration.
内容的提问来源于stack exchange,提问作者Lola

