使用drf-nested-routers遇URL解析错误,无法获取Section详情
Hey there! Let's break down what's going wrong here and fix it step by step.
Key Issues Identified
Mismatched Lookup Fields
YourCourseandSectionmodels use custom primary keys (course_codeandsection_numberrespectively), but the default viewset behavior expects the standardpkfield. This causes URL resolution failures when fetching details.Incorrect View Names for Nested Routes
Thedrf-nested-routersgenerates view names in the format<parent-lookup>-<route>-detail(e.g.,parent_course-sections-detail), but your serializers were referencing the genericsection-detailwhich doesn't exist in the nested setup.Unfiltered Section Queries
YourSectionViewSetwasn't filtering results by the parent course from the URL, so it tried to return all sections regardless of the course context.
Fixed Code Implementation
/views.py
from . import models from . import serializers from rest_framework import viewsets class CourseViewSet(viewsets.ModelViewSet): serializer_class = serializers.CourseSerializer queryset = models.Course.objects.all() # Match the custom primary key of Course model lookup_field = 'course_code' class SectionViewSet(viewsets.ModelViewSet): serializer_class = serializers.SectionSerializer queryset = models.Section.objects.all() # Match the custom primary key of Section model lookup_field = 'section_number' def get_queryset(self): # Filter sections to only those linked to the parent course in the URL parent_course_code = self.kwargs.get('parent_course_pk') if parent_course_code: return self.queryset.filter(parent_course__course_code=parent_course_code) return super().get_queryset()
/serializers.py
from rest_framework_nested.relations import NestedHyperlinkedRelatedField from rest_framework_nested.serializers import NestedHyperlinkedModelSerializer from rest_framework import serializers from . import models class CourseSerializer(serializers.HyperlinkedModelSerializer): sections_offered = NestedHyperlinkedRelatedField( many=True, read_only=True, # Use the correct nested view name generated by the router view_name='parent_course-sections-detail', parent_lookup_kwargs={'parent_course_pk': 'parent_course__course_code'} ) class Meta: model = models.Course fields = ("url", "course_code", "sections_offered",) # Ensure the course URL uses the custom primary key extra_kwargs = {'url': {'lookup_field': 'course_code'}} class SectionSerializer(NestedHyperlinkedModelSerializer): class Meta: model = models.Section fields = "__all__" # Map the nested route parameters to model fields parent_lookup_kwargs = {'parent_course_pk': 'parent_course__course_code'} # Ensure the section URL uses its custom primary key extra_kwargs = {'url': {'lookup_field': 'section_number'}}
/urls.py (no changes needed, just confirmation)
Your existing setup is correct— the NestedSimpleRouter generates the right view names that we now reference in the serializers:
from rest_framework import routers from . import views from rest_framework_nested.routers import NestedSimpleRouter from django.conf.urls import url, include router = routers.DefaultRouter() router.register(r'courses', views.CourseViewSet) courses_router = NestedSimpleRouter(router, r'courses', lookup='parent_course') courses_router.register(r'sections', views.SectionViewSet) urlpatterns = [ url(r'^', include(router.urls)), url(r'^', include(courses_router.urls)), ]
What These Changes Fix
/courses/CS250/sections/will now only list sections belonging to CS250 (even after creating sections)- The section detail URL (
/courses/CS250/sections/01/) resolves correctly without errors - The
sections_offeredlinks in course detail responses point to valid nested section URLs - Both models use their custom primary keys for URL lookup, matching your database structure
内容的提问来源于stack exchange,提问作者Steve Hemmingsen

