0

I read a lot about problems affecting hyperlink on DRF when namespaces are used. But I didnt manage to resolve my problem by following the tips and recommandations on both Github and Stackoverflow so far.

I have recently added namespaces to my urls.py

urlpatterns = patterns('',
                    # API
                    url(r'^api/', include(core_api_router.urls, namespace='api')),
                    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')),
                    url(r'^api-docs/', include('rest_framework_swagger.urls', namespace='api_docs'), name='api_docs'),
                   )

Here is my api.py

class MyBaseModelSerializer(DynamicModelSerializerMixin, serializers.ModelSerializer):

    status = serializers.HyperlinkedRelatedField(many=True, view_name='api:mybasemodel', read_only=True)

        class Meta:
            model = models.MyBaseModel
            fields = ('id', 'href', 'url', 'sid', 'name', 'status', 'created',)
            ordering_fields = '__all__'
            ordering = ('name',)

class ChangeViewSet(viewsets.ModelViewSet):
    queryset = models.MyBaseModel.objects.all().select_related('status')
    serializer_class = MyBaseModelSerializer

router.register('core/mybasemodel', MyBaseModelViewSet)


class MyRelatedModelSerializer(serializers.ModelSerializer):

    id = serializers.UUIDField(read_only=True)
    href = serializers.HyperlinkedIdentityField(view_name='api:myrelatedmodel')

        class Meta:
            fields = ('id', 'href', 'key', 'comment', 'position', 'created')
            ordering_fields = '__all__'
            ordering = ('position',)

class MyRelatedViewSet(viewsets.ModelViewSet):
    queryset = models.MyRelatedModel.objects.all()
    serializer_class = MyRelatedSerializer

 router.register('core/myrelatedmodel', MyRelatedModelViewSet)

In my test I check whether I can modify an existing object via the API

def test_api_update(self):
    # Create an entry
    entry = self.Meta.factory.create()

    url = reverse('api:'+self.api_model_url+'-detail', args=[str(entry.id)])

    data = {'sid': 'Modified Entry'}

    # Check that an entry can be altered by an administrator via the API
    self.api_client.login(username='admin', password='admin')
    response = self.api_client.patch(url, data, format='json')
    content = self.parse_json_response(response, Status.HTTP_200_OK)
    self.assertEqual(content['sid'], 'Modified Entry')

Django raises this exception:

django.core.exceptions.ImproperlyConfigured: Could not resolve URL for hyperlinked relationship using view name "mybasemodel-detail". You may have failed to include the related model in your API, or incorrectly configured the `lookup_field` attribute on this field.
dmw.apps.core.views: ERROR: E500 : 127.0.0.1 : admin-user : http://testserver/api/core/api:mybasemodel/121e6850-3cd8-4795-d9bc-axsa04d1bd12/

My application runs on Python 3.4 with Django 1.8.9, Django Rest Framework 3.3.2 and I have tried with both:

router = routers.DefaultRouter()

and

routeur = routeurs.SimpleRouter()

Thanks in advance for your help!

Cheers!

2
  • It still doesn't work but I don't have the time to investigate further at the moment.. I'll accept your answer because it's a first step in the resolution of this problem! :) Commented Mar 15, 2016 at 14:08
  • It should work with both simple and default router right? Commented Mar 15, 2016 at 14:13

2 Answers 2

2

Looks like the problem is in the HyperlinkedIdentityField of your two serializers MyBaseModelSerializer and MyRelatedModelSerializer. In view_name you have to specify the the full name, not only the basename like you did. From the docs

view_name - The view name that should be used as the target of the relationship. If you're using the standard router classes this will be a string with the format -detail.

So you should add -detail there (like you do in your test):

# MyBaseModelSerializer
status = serializers.HyperlinkedRelatedField(many=True, view_name='api:mybasemodel-detail', read_only=True)

# MyRelatedModelSerializer
href = serializers.HyperlinkedIdentityField(view_name='api:myrelatedmodel-detail')
Sign up to request clarification or add additional context in comments.

Comments

0

Encountered Similar problem, Solved by correcting the fields in serializer.py . Check your fields corresponding to model fields. Any unmatched fields will produce this kind of error.

For Example my default Auth model has following fields: (defaults fields from Django Auth Model after running migrations)

id, first_name , last_name, password, username,last_login, is_active, is_active, date_joined and email

what serializer does is: Pick up specified fields from your model , then convert it to json for API processing.

So this error raises if you order your serializer to pick up those fields which are certainly not present in your database of same model(table).

I hope it solves. :)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.