DRF嵌套路由器无法解析超链接关系的URL

时间:2018-06-17 10:42:15

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

我正在尝试使用drf-nested-routers创建一个嵌套的url模式,如下所示:

/projects/{project_pk}/join_request/{pk}

使用我当前的设置,我能够成功导航到/projects,并查看超链接的join_requests列表:

[
    {
        "url": "http://127.0.0.1:8000/projects/1/",
        "join_requests": [
            "http://127.0.0.1:8000/projects/1/join_requests/1/",
            "http://127.0.0.1:8000/projects/1/join_requests/2/"
        ],
        "name": "Sample Project"
    }
]

但是,当我点击进入join_request时,我收到以下错误:

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

作为一名DRF初学者,在做了大量研究之后,我无法确定我哪里出错了。如果有人可以发布一个例子,或者建议我配置错误的地方,我将不胜感激:

在models.py中,我有:

class Project(models.Model):
    name = models.TextField()  # what is the name of the project

class ProjectJoinRequest(models.Model):
    request = models.TextField()
    user = models.ForeignKey(User, on_delete=models.CASCADE, related_name="join_requests", blank=True, null=True)
    project = models.ForeignKey(Project, on_delete=models.CASCADE, related_name="join_requests", blank=True, null=True)

class User(AbstractUser):
    name = models.TextField()

在serializers.py中:

from rest_framework_nested.relations import NestedHyperlinkedRelatedField

class ProjectSerializer(serializers.HyperlinkedModelSerializer):

    join_requests = NestedHyperlinkedRelatedField(
        many=True,
        read_only=True,
        view_name='projectjoinrequest-detail',
        parent_lookup_kwargs={'project_pk': 'project__pk'}
    )

    class Meta:
        model = models.Project
        fields = ["join_requests", "name"]

class ProjectJoinRequestSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = models.ProjectJoinRequest
        fields = "__all__"

在views.py中:

class ProjectViewSet(viewsets.ViewSet):
    serializer_class = serializers.ProjectSerializer
    queryset = models.Project.objects.all()

    def list(self, request):
        queryset = models.Project.objects.filter()
        serializer = serializers.ProjectSerializer(queryset, many=True, context={"request" : request})
        return Response(serializer.data)

    def retrieve(self, request, pk=None):
        queryset = models.Project.objects.filter()
        project = get_object_or_404(queryset, pk=pk)
        serializer = serializers.ProjectSerializer(project, context={"request": request})
        return Response(serializer.data)

class ProjectJoinRequestViewSet(viewsets.ViewSet):
    serializer_class = serializers.ProjectJoinRequestSerializer
    queryset = models.ProjectJoinRequest.objects.all()

    def list(self, request, project_pk=None):
        queryset = models.ProjectJoinRequest.objects.filter(project=project_pk)
        serializer = serializers.ProjectJoinRequestSerializer(queryset, many=True, context={'request': request})
        return Response(serializer.data)

    def retrieve(self, request, pk=None, project_pk=None):
        queryset = models.ProjectJoinRequest.objects.filter(pk=pk, project=project_pk)
        project_join_request = get_object_or_404(queryset, pk=pk)
        serializer = serializers.ProjectJoinRequestSerializer(project_join_request, context={'request': request})
        return Response(serializer.data)

和urls.py:

router = routers.DefaultRouter()
router.register(r'projects', views.ProjectViewSet)
projects_router = routers.NestedSimpleRouter(router, r'projects', lookup='project')
projects_router.register(r'join_requests', views.ProjectJoinRequestViewSet)
urlpatterns = [
    url(r'^', include(router.urls)),
    url(r'^', include(projects_router.urls)),
]

0 个答案:

没有答案