mayank gupta
mayank gupta

Reputation: 19

I am following a Django REST API tutorial. However, getting error? (Topic: serializers.HyperlinkedModelSerializer)

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

Getting the Error mentioned above while hitting the URL (127.0.0.1:8000/watch/stream/)

Models.py

from django.db import models

class StreamPlatform(models.Model):
    name = models.CharField(max_length=30)
    about = models.CharField(max_length=150)
    website = models.URLField(max_length=100)

    def __str__(self):
        return self.name

class WatchList(models.Model):
    title = models.CharField(max_length=50)
    storyline = models.CharField(max_length=200)
    platform = models.ForeignKey(StreamPlatform, on_delete=models.CASCADE, related_name="watchlist")
    active = models.BooleanField(default=True)
    created = models.DateTimeField(auto_now_add=True)

    def __str__(self):
        return self.title

urls.py

from django.urls import path, include
from watchlist_app.api.views import WatchListAV, WatchDetailAV, StreamPlatformAV, StreamDetailAV

urlpatterns = [
    path('list/', WatchListAV.as_view(), name='movie-list'),
    path('<int:pk>/', WatchDetailAV.as_view(), name='movie-details'),
    path('stream/', StreamPlatformAV.as_view(), name='stream-list'),
    path('stream/<int:pk>/', StreamDetailAV.as_view(), name='stream-details'),
]

views.py

from rest_framework.response import Response
from rest_framework.views import APIView
from rest_framework import status
from watchlist_app.models import WatchList, StreamPlatform
from watchlist_app.api.serializers import WatchListSerializer, StreamPlatformSerializer


class StreamPlatformAV(APIView):

    def get(self, request):
        platform = StreamPlatform.objects.all()
        Serializer = StreamPlatformSerializer(platform, many=True, context={'request': request})
        return Response(Serializer.data)

    def post(self, request):
        serializer = StreamPlatformSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        else:
            return Response(serializer.errors)


class StreamDetailAV(APIView):

    def get(self, request, pk):
        try:
            platform = StreamPlatform.objects.get(pk=pk)
        except StreamPlatform.DoesNotExist:
            return Response({'error': 'Not found'}, status=status.HTTP_404_NOT_FOUND)

        serializer = StreamPlatformSerializer(platform)
        return Response(serializer.data)

    def put(self, request, pk):
        platform = StreamPlatform.objects.get(pk=pk)
        serializer = StreamPlatformSerializer(platform, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk):
        platform = WatchList.objects.get(pk=pk)
        platform.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)


class WatchListAV(APIView):

    def get(self, request):
        movies = WatchList.objects.all()
        Serializer = WatchListSerializer(movies, many=True)
        return Response(Serializer.data)

    def post(self, request):
        serializer = WatchListSerializer(data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        else:
            return Response(serializer.errors)


class WatchDetailAV(APIView):

    def get(self, request, pk):
        try:
            movie = WatchList.objects.get(pk=pk)
        except WatchList.DoesNotExist:
            return Response({'error': 'Not found'}, status=status.HTTP_404_NOT_FOUND)

        serializer = WatchListSerializer(movie)
        return Response(serializer.data)

    def put(self, request, pk):
        movie = WatchList.objects.get(pk=pk)
        serializer = WatchListSerializer(movie, data=request.data)
        if serializer.is_valid():
            serializer.save()
            return Response(serializer.data)
        else:
            return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)

    def delete(self, request, pk):
        movie = WatchList.objects.get(pk=pk)
        movie.delete()
        return Response(status=status.HTTP_204_NO_CONTENT)

serializer.py

from rest_framework import serializers
from watchlist_app.models import WatchList, StreamPlatform


class WatchListSerializer(serializers.ModelSerializer):

    class Meta:
        model = WatchList
        fields = "__all__"
        

class StreamPlatformSerializer(serializers.HyperlinkedModelSerializer):

    watchlist = WatchListSerializer(many=True, read_only=True)

    class Meta:
        model = StreamPlatform
        fields = "__all__"

Upvotes: 0

Views: 1472

Answers (3)

Shubham Sarda
Shubham Sarda

Reputation: 635

Here are 3 solutions that will fix almost all errors related to HyperlinkedModelSerializer.

  1. The recommended URL view name is '{model_name}-detail'. If possible change you name to streamplatform-detail and it should solve the problem.

  2. Make sure you have included the request in the serializer context. Just pass context={'request': request} and it should be fine.

  3. By default lookup_field='id' and the URL pattern it follows help to fetch the id but sometimes students do edit the pattern and that's why you need to specifically mention lookup_field='id'.

Upvotes: 4

romina
romina

Reputation: 66

By changing your name='stream-details' in your urls.py into name=" stream platform-detail" the problem has to be solved.

 path('stream/<int:pk>', StreamDetailAV.as_view(), name="streamplatform-detail")

I hope this helps you

Upvotes: 4

Inderpal Singh
Inderpal Singh

Reputation: 101

Step 1.

    path('', include('testapp.api.urls', namespace="testapp")),

Step 2. add in urls.py file which is in application folder.

    app_name = 'testapp'

step 3.

 class StreamPlatformSerializer(serializers.HyperlinkedModelSerializer):
        watchlist_platform = WatchListSerializer(many=True, read_only=True)
        url = serializers.HyperlinkedIdentityField(view_name="testapp:stream-detail")

Step 4

       serializer = StreamPlatformSerializer(platform, many=True, context={'request': request})

And it solved my problem.

Upvotes: 0

Related Questions