[django] Could not resolve URL for hyperlinked relationship using view name “-detail” [SOLVED]

When trying to build my first rest-django app, i faced below error message, which was not easy to solve:

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.

For simplicity reason, below example is based on django-rest-framework tutorial, where project is named “tutorial” and one app called “snippets” is created inside this project

After investigation, the following happens:

  1. in snippets/urls.py, ensure to use “name=” attribute as per below, and use the convention of ‘<model>-detail’ for detail view and ‘<model>-list’ for bulk list view:
    url(r'^snippets/$', views.SnippetList.as_view(), name='snippet-list'),
    url(r'^snippets/(?P<pk>[0-9]+)/$', views.SnippetDetail.as_view(), name='snippet-detail'),
    url(r'^snippets/(?P<pk>[0-9]+)/highlight/$', views.SnippetHighlight.as_view(), name='snippet-highlight'),
  2. go to tutorial/urls.py (i.e. project level urls) and check if any namespace is used:
    url(r'^', include('snippets.urls', namespace='rdtest')),

    note: in this case, a particular namespace ‘rdtest’ is used

  3. go to snippets/serializers.py, since a namespace is defined in project level urls, this namespace must be specified in the serializer class.
    This is achieved by adding some extra-arguments as per below:

    class SnippetSerializer(serializers.HyperlinkedModelSerializer):
      owner = serializers.ReadOnlyField(source='owner.username')
      highlight = serializers.HyperlinkedIdentityField(view_name='rdtest:snippet-highlight', format='html')
    
      class Meta:
        model = Snippet
        fields = ('url', 'highlight', 'owner', 'title', 'code', 'linenos', 'language', 'style')
        extra_kwargs = {'url': {'view_name': 'rdtest:snippet-detail'}}
  4. make sure that regular expression used in snippets/urls.py is indeed matching your primary key field definition.
    in my case,  changing url definition from:

    url(r'^snippets/(?P<pk>[0-9]+)/$', views.SnippetDetail.as_view(), name='snippet-detail'),

    to:

    url(r'^snippets/(?P<pk>.+)/$', views.SnippetDetail.as_view(), name='snippet-detail'),

    solved the issue.
    Reason is I changed my primary key in snippets/models.py to be a UUID field instead of automatically incrementing numeric value.
    UUID fields are hexadecimal characters grouped through hypen (ex: ‘a8098c1a-f86e-11da-bd1a-00112444be1e’) and were not matched by initial regular expression which was expecting only digits.
    For information purposes, my snippets/models.py file looks like below for Snippet class:

      id          = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)

     

Issue solved.

sources

One Comment Trackback URL | Comments RSS

  1. mateosss Says:

    Thanks!!! This was driving me crazy

Post a Comment

Your email is never published nor shared. You're allow to say what you want...