DRF嵌套路由器:URL配置不正确

时间:2017-06-18 19:21:35

标签: django django-rest-framework drf-nested-routers

我正在尝试使用DRF的快速入门指南构建应用程序。该应用程序具有以下设置

/school/
/school/<pk>
/school/<pk>/courses/
/school/<pk>/courses/<pk>
/school/<pk>/courses/<pk>/members/

当我按照快速入门时出现以下错误

ImproperlyConfigured at /api/v1/school/1/courses/1/members/
Could not resolve URL for hyperlinked relationship using view name "courses-detail". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field.

访问时

/school/<pk>/courses/<pk>/members/

我真的不明白我得到的错误信息,因为我有视图名称“courses-detail”随时可用。有人能帮我清楚我做错了吗?

这是我在示例应用程序中的代码。

views.py

# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.shortcuts import render, get_object_or_404
from rest_framework import viewsets, permissions
from rest_framework.response import Response

from .serializers import SchoolSerializer, SchoolActivitySerializer, SchoolCourseSerializer, CourseSerializer, ActivitySerializer, SchoolCourseMemberSerializer, MemberSerializer
from .models import School, Course, Activity, Member


# Create your views here.
class SchoolViewset(viewsets.ModelViewSet):
    serializer_class = SchoolSerializer
    queryset = School.objects.all()


class CourseViewset(viewsets.ModelViewSet):
    serializer_class = CourseSerializer
    queryset = Course.objects.all()

    def get_school(self, school_pk):
        school = get_object_or_404(School.objects.all(), pk=school_pk)
        return school

    def list(self, request, *args, **kwargs):

        queryset = Course.objects.all()
        serializer = CourseSerializer(queryset, many=True)
        return Response(serializer.data)


class MemberViewset(viewsets.ModelViewSet):
    serializer_class = MemberSerializer
    queryset = Member.objects.all()

class ActivityViewset(viewsets.ModelViewSet):
    serializer_class = ActivitySerializer
    queryset = Activity.objects.all()

    def list(self, request, *args, **kwargs):
        queryset = Activity.objects.filter()
        serializer = ActivitySerializer(queryset, many=True)
        return Response(serializer.data)

class SchoolCourseMemberViewset(viewsets.ModelViewSet):
    serializer_class = SchoolCourseMemberSerializer
    queryset = Member.objects.all()

serializers.py

from rest_framework import serializers
from rest_framework_nested import serializers as nested_serializers
from rest_framework_nested import relations
from .models import School, Course, Activity, Member


class CourseSerializer(serializers.ModelSerializer):
    class Meta:
        model = Course
        fields = ('course_name', 'course_date', 'course_school',)


class ActivitySerializer(serializers.ModelSerializer):
    class Meta:
        model = Activity
        fields = ('activity_name', 'activity_location', 'activity_school', 'activity_date', 'activity_price',)


class MemberSerializer(serializers.ModelSerializer):
    class Meta:
        model = Member
        fields = ('user', 'ranking',)


class SchoolCourseSerializer(nested_serializers.NestedHyperlinkedModelSerializer):
    parent_lookup_kwargs = {
        'school_pk': 'course_school',
    }

    class Meta:
        model = Course
        fields = ('id', 'course_name', 'course_date',)


class SchoolCourseMemberSerializer(nested_serializers.NestedHyperlinkedModelSerializer):
    courses_lookup_kwargs = {
        'school_pk': 'school__pk',
        'course_pk': 'course__pk',
    }
    courses = relations.NestedHyperlinkedRelatedField(parent_lookup_kwargs={'course_school_pk': 'course_school__pk'}, view_name='courses-detail', queryset=Course.objects.all())

    class Meta:
        model = Member
        fields = ('url', 'user', 'ranking', 'courses', )


class SchoolActivitySerializer(nested_serializers.NestedHyperlinkedModelSerializer):

    class Meta:
        model = Activity
        fields = ('activity_name', 'activity_location', 'activity_date', 'activity_price',)


class SchoolMemberSerializer(nested_serializers.NestedHyperlinkedModelSerializer):

    class Meta:
        model = Member
        fields = ('user', 'ranking',)


class SchoolSerializer(serializers.ModelSerializer):

    class Meta:
        model = School
        fields = ('id', 'url', 'school_name', 'school_address', 'courses', 'activities', 'members', )

    courses = SchoolCourseSerializer(many=True, read_only=True)
    activities = SchoolActivitySerializer(many=True, read_only=True)
    members = SchoolMemberSerializer(many=True, read_only=True)

models.py

from __future__ import unicode_literals

from django.db import models
from django.contrib.auth.models import User
from django.db.models.signals import post_save
from django.dispatch import receiver

# Create your models here.
class School(models.Model):
    school_name = models.CharField(max_length=30, verbose_name='Name', help_text="The name of the school.")
    school_address = models.CharField(max_length=30, verbose_name='Address', help_text="The location of the school.")


class Course(models.Model):
    course_name = models.CharField(max_length=30)
    course_date = models.DateTimeField(auto_now_add=True)
    course_school = models.ForeignKey(School, related_name='courses')


class Activity(models.Model):
    activity_name = models.CharField(max_length=30)
    activity_location = models.CharField(max_length=30)
    activity_school = models.ForeignKey(School, related_name='activities')
    activity_date = models.DateTimeField(auto_now_add=True)
    activity_price = models.DecimalField(decimal_places=2, max_digits=11, verbose_name='price')

class Member(models.Model):
    user = models.OneToOneField(User, on_delete=models.CASCADE)
    ranking = models.IntegerField(verbose_name='ranking', blank=False)

    #users = User.objects.all().select_related('profile')

@receiver(post_save, sender=User)
def create_user_member(sender, instance, created, **kwargs):
    if created:
        Member.objects.create(user=instance)

@receiver(post_save, sender=User)
def save_user_member(sender, instance, **kwargs):
    instance.member.save

urls.py

from django.conf.urls import url, include
from rest_framework_nested import routers

from .views import SchoolViewset, CourseViewset, ActivityViewset, MemberViewset, SchoolCourseMemberViewset

router_1 = routers.SimpleRouter()
router_1.register('school', SchoolViewset, base_name='school')
school_router = routers.NestedSimpleRouter(router_1, r'school', lookup='school')
school_router.register(r'activities', ActivityViewset, base_name='activities')
school_router.register(r'courses', CourseViewset, base_name='courses')
school_router.register(r'members', MemberViewset, base_name='members')

school_member_router = routers.NestedSimpleRouter(school_router, r'courses', lookup='courses')
school_member_router.register('members', SchoolCourseMemberViewset, base_name='members')



urlpatterns = [
    url(r'', include(router_1.urls)),
    url(r'', include(school_router.urls)),
    url(r'', include(school_member_router.urls)),
]

如果我未能包含解决错误所需的任何信息,请告诉我。我很乐意提供任何其他信息。

提前致谢。

0 个答案:

没有答案