Django REST Framework - Could not resolve URL for hyperlinked relationship using view name

This post is from 2013, it is probably out of date.

Here's an error that's all too easy to stumble on if you are just hacking your way into an API using Django REST Framework

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

Recreating the error

I'll assume you have, at least, a basic Django site up and running. Perhaps you are a little impatient (like me) and you skim the Django REST Framework's homepage. You add the following in to settings.py:
REST_FRAMEWORK = {
# Use hyperlinked styles by default.
# Only used if the `serializer_class` attribute is not set on a view.
'DEFAULT_MODEL_SERIALIZER_CLASS':
'rest_framework.serializers.HyperlinkedModelSerializer',

# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
]
}

And then, somehow, you skip the rest of the tutorial and you end up with something like this:

class Pet(models.Model):
name = models.CharField(max_length=250)
date_of_birth = models.DateTimeField()

def __unicode__(self):
return self.name

## views.py:
from .models import Pet
from rest_framework.generics import(
ListCreateAPIView
)

class PetAPIListCreateView(ListCreateAPIView):
model = Pet


## urls.py:
from django.conf.urls import patterns, include, url
from .views import PetAPIListCreateView

urlpatterns = patterns('',
url(r'^api/$', PetAPIListCreateView.as_view()),
)

Make sure you run your migration or sync your db.

Now you should be able to browse your api with the following url:

http://localhost:8000/pets/api

Now add some data into your Pet table and refresh your api endpoint.

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

Fix

There are two methods to fix this - the first (possibly simplest) is to cut the following out of settings.py (commented out so you don't skim my post and add it in again): ```python #REST_FRAMEWORK = { # # Use hyperlinked styles by default. # # Only used if the `serializer_class` attribute is not set on a view. # 'DEFAULT_MODEL_SERIALIZER_CLASS': # 'rest_framework.serializers.HyperlinkedModelSerializer', # # # Use Django's standard `django.contrib.auth` permissions, # # or allow read-only access for unauthenticated users. # 'DEFAULT_PERMISSION_CLASSES': [ # 'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly' # ] #} ``` In actual fact, removing just the following two lines will fix it for you: ```python #'DEFAULT_MODEL_SERIALIZER_CLASS': #'rest_framework.serializers.HyperlinkedModelSerializer', ``` The second is to create a serializers.py class like so: ```python from rest_framework import serializers from .models import Pet class PetSerializer(serializers.ModelSerializer): class Meta: model=Pet fields =('id','name','date_of_birth') ``` and update your views.py as follows: ```python from .models import Pet from .serializers import PetSerializer from rest_framework.generics import( ListCreateAPIView ) class PetAPIListCreateView(ListCreateAPIView): queryset = Pet.objects.all() serializer_class = PetSerializer ```

Why does this happen?

Well, the key lies in the Default Model Serializer Class - when it is set to HyperlinkedModelSerializer, the rest framework needs a serializer to work with.