bpipat bpipat - 4 months ago 38
Python Question

Django Rest Framework - Could not resolve URL for hyperlinked relationship using view name "user-detail"

I am building a project in Django Rest Framework where users can login to view their wine cellar.
My ModelViewSets were working just fine and all of a sudden I get this frustrating error:


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


The traceback shows:

[12/Dec/2013 18:35:29] "GET /bottles/ HTTP/1.1" 500 76677
Internal Server Error: /bottles/
Traceback (most recent call last):
File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/django/core/handlers/base.py", line 114, in get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/rest_framework/viewsets.py", line 78, in view
return self.dispatch(request, *args, **kwargs)
File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/django/views/decorators/csrf.py", line 57, in wrapped_view
return view_func(*args, **kwargs)
File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/rest_framework/views.py", line 399, in dispatch
response = self.handle_exception(exc)
File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/rest_framework/views.py", line 396, in dispatch
response = handler(request, *args, **kwargs)
File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/rest_framework/mixins.py", line 96, in list
return Response(serializer.data)
File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/rest_framework/serializers.py", line 535, in data
self._data = [self.to_native(item) for item in obj]
File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/rest_framework/serializers.py", line 325, in to_native
value = field.field_to_native(obj, field_name)
File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/rest_framework/relations.py", line 153, in field_to_native
return self.to_native(value)
File "/Users/bpipat/.virtualenvs/usertest2/lib/python2.7/site-packages/rest_framework/relations.py", line 452, in to_native
raise Exception(msg % view_name)
Exception: Could not resolve URL for hyperlinked relationship using view
name "user-detail". You may have failed to include the related model in
your API, or incorrectly configured the `lookup_field` attribute on this
field.


I have a custom email user model and the bottle model in models.py is:

class Bottle(models.Model):
wine = models.ForeignKey(Wine, null=False)
user = models.ForeignKey(User, null=False, related_name='bottles')


My serializers:

class BottleSerializer(serializers.HyperlinkedModelSerializer):

class Meta:
model = Bottle
fields = ('url', 'wine', 'user')

class UserSerializer(serializers.ModelSerializer):

class Meta:
model = User
fields = ('email', 'first_name', 'last_name', 'password', 'is_superuser')


My views:

class BottleViewSet(viewsets.ModelViewSet):
"""
API endpoint that allows bottles to be viewed or edited.
"""
queryset = Bottle.objects.all()
serializer_class = BottleSerializer

class UserViewSet(ListCreateAPIView):
"""
API endpoint that allows users to be viewed or edited.
"""
queryset = User.objects.all()
serializer_class = UserSerializer


and finally the url:

router = routers.DefaultRouter()
router.register(r'bottles', views.BottleViewSet, base_name='bottles')

urlpatterns = patterns('',
url(r'^', include(router.urls)),
# ...


I don't have a user detail view and I don't see where this issue could come from. Any ideas?

Thanks

Answer

Because it's a HyperlinkedModelSerializer your serializer is trying to resolve the URL for the related User on your Bottle.
As you don't have the user detail view it can't do this. Hence the exception.

  1. Would not just registering the UserViewSet with the router solve your issue?
  2. You could define the user field on your BottleSerializer to explicitly use the UserSerializer rather than trying to resolve the URL. See the serializer docs on dealing with nested objects for that.