2
votes

Previously I was using ModelSerializer and there were no error. When I replaced it with HyperlinkedModelSerializer this error was thrown

Could not resolve URL for hyperlinked relationship using view name "book
detail". You may have failed to include the related model in your API,
or incorrectly configured the `lookup_field` attribute on this field.

this is serializers.py file:

class BookSerializer(serializers.HyperlinkedModelSerializer):
    class Meta:
        model = Book
        fields = ['id', 'url', 'title', 'subtitle', 'isbn']

model.py

class Book(models.Model):
    title = models.CharField(max_length=250)
    subtitle = models.CharField(max_length=250)
    author = models.CharField(max_length=100)
    isbn = models.CharField(max_length=13)

    def __str__(self):
        return self.title

views.py

class BookListView(viewsets.ModelViewSet):
    queryset = Book.objects.all()
    serializer_class = BookSerializer

and urls.py

router = routers.DefaultRouter()
router.register('books', BookListView)


app_name = "books"
urlpatterns = [
    path('', include(router.urls)),
]

view name book-detail doesn't exist in my views, probably Django created it automatically and I don't know where to find and debug it? Thank you.

here is the traceback of error -

Environment:


Request Method: GET
Request URL: http://localhost:8000/books/

Django Version: 3.1.2
Python Version: 3.8.5
Installed Applications:
['django.contrib.admin',
 'django.contrib.auth',
 'django.contrib.contenttypes',
 'django.contrib.sessions',
 'django.contrib.messages',
 'django.contrib.staticfiles',
 'rest_framework',
 'books.apps.BooksConfig']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
 'django.contrib.sessions.middleware.SessionMiddleware',
 'django.middleware.common.CommonMiddleware',
 'django.middleware.csrf.CsrfViewMiddleware',
 'django.contrib.auth.middleware.AuthenticationMiddleware',
 'django.contrib.messages.middleware.MessageMiddleware',
 'django.middleware.clickjacking.XFrameOptionsMiddleware']



Traceback (most recent call last):
  File "D:\All\Back-end Django\REST API Django\lib\site-packages\rest_framework\relations.py", line 398, in to_representation
    url = self.get_url(value, self.view_name, request, format)
  File "D:\All\Back-end Django\REST API Django\lib\site-packages\rest_framework\relations.py", line 336, in get_url
    return self.reverse(view_name, kwargs=kwargs, request=request, format=format)
  File "D:\All\Back-end Django\REST API Django\lib\site-packages\rest_framework\reverse.py", line 47, in reverse
    url = _reverse(viewname, args, kwargs, request, format, **extra)
  File "D:\All\Back-end Django\REST API Django\lib\site-packages\rest_framework\reverse.py", line 60, in _reverse
    url = django_reverse(viewname, args=args, kwargs=kwargs, **extra)
  File "D:\All\Back-end Django\REST API Django\lib\site-packages\django\urls\base.py", line 87, in reverse
    return iri_to_uri(resolver._reverse_with_prefix(view, prefix, *args, **kwargs))
  File "D:\All\Back-end Django\REST API Django\lib\site-packages\django\urls\resolvers.py", line 685, in _reverse_with_prefix
    raise NoReverseMatch(msg)

During handling of the above exception (Reverse for 'book-detail' not found. 'book-detail' is not a valid view function or pattern name.), another exception occurred:
  File "D:\All\Back-end Django\REST API Django\lib\site-packages\django\core\handlers\exception.py", line 47, in inner
    response = get_response(request)
  File "D:\All\Back-end Django\REST API Django\lib\site-packages\django\core\handlers\base.py", line 179, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "D:\All\Back-end Django\REST API Django\lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
    return view_func(*args, **kwargs)
  File "D:\All\Back-end Django\REST API Django\lib\site-packages\rest_framework\viewsets.py", line 125, in view
    return self.dispatch(request, *args, **kwargs)
  File "D:\All\Back-end Django\REST API Django\lib\site-packages\rest_framework\views.py", line 509, in dispatch
    response = self.handle_exception(exc)
  File "D:\All\Back-end Django\REST API Django\lib\site-packages\rest_framework\views.py", line 469, in handle_exception
    self.raise_uncaught_exception(exc)
  File "D:\All\Back-end Django\REST API Django\lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
    raise exc
  File "D:\All\Back-end Django\REST API Django\lib\site-packages\rest_framework\views.py", line 506, in dispatch
    response = handler(request, *args, **kwargs)
  File "D:\All\Back-end Django\REST API Django\lib\site-packages\rest_framework\mixins.py", line 46, in list
    return Response(serializer.data)
  File "D:\All\Back-end Django\REST API Django\lib\site-packages\rest_framework\serializers.py", line 745, in data
    ret = super().data
  File "D:\All\Back-end Django\REST API Django\lib\site-packages\rest_framework\serializers.py", line 246, in data
    self._data = self.to_representation(self.instance)
  File "D:\All\Back-end Django\REST API Django\lib\site-packages\rest_framework\serializers.py", line 663, in to_representation
    return [
  File "D:\All\Back-end Django\REST API Django\lib\site-packages\rest_framework\serializers.py", line 664, in <listcomp>
    self.child.to_representation(item) for item in iterable
  File "D:\All\Back-end Django\REST API Django\lib\site-packages\rest_framework\serializers.py", line 515, in to_representation
    ret[field.field_name] = field.to_representation(attribute)
  File "D:\All\Back-end Django\REST API Django\lib\site-packages\rest_framework\relations.py", line 413, in to_representation
    raise ImproperlyConfigured(msg % self.view_name)

Exception Type: ImproperlyConfigured at /books/
Exception Value: Could not resolve URL for hyperlinked relationship using view name "book-detail". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field.
1
The code is working on my end and I am able to create a new book via the api: 127.0.0.1:8000/api/books Have you modified the model and forgot to rerun migrations? Restart your server and try again? If it still doesn't work, can you provide the error message?Zhivko Zaikov
Yes, I rerun the migrations. restarted the server and I am still getting the error. I just added the traceback.Mir Stephen
Still no error on my end and everything is working properly. I would test this by modifying the "app_name = "books"" to something else as they may overlap with the router URL or try creating another model with the same fields, serializer, view and check if it worksZhivko Zaikov
I even created a new project and I am still getting the same error.Mir Stephen

1 Answers

2
votes

I once faced this problem too but I fixed by doing this:

urls.py (project)
you might need to provide namespace for your app in root urls.py

path('your_url', include(('your_app.urls', 'your_app'), namespace="your_app"))

serializers.py
add a HyperlinkedIdentityField

class BookSerializer(serializers.HyperlinkedModelSerializer):
    # add this 
    url = serializers.HyperlinkedIdentityField(view_name="your_app:book-detail")

    class Meta:
        model = Book
        fields = ['id', 'url', 'title', 'subtitle', 'isbn']

urls.py (app)
add basename

router = routers.DefaultRouter()
# add basename
router.register('books', BookListView, basename="books")

Docs https://www.django-rest-framework.org/tutorial/5-relationships-and-hyperlinked-apis/