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)),
]