diff --git a/rest_framework/fields.py b/rest_framework/fields.py index c28a9695a..8a6b36b54 100644 --- a/rest_framework/fields.py +++ b/rest_framework/fields.py @@ -582,6 +582,9 @@ class HyperlinkedRelatedField(RelatedField): if self.queryset is None: raise Exception('Writable related fields must include a `queryset` argument') + if value is None: + return None + if value.startswith('http:') or value.startswith('https:'): # If needed convert absolute URLs to relative path value = urlparse(value).path diff --git a/rest_framework/tests/hyperlinkedserializers.py b/rest_framework/tests/hyperlinkedserializers.py index d7effce70..df894fcc2 100644 --- a/rest_framework/tests/hyperlinkedserializers.py +++ b/rest_framework/tests/hyperlinkedserializers.py @@ -3,6 +3,7 @@ from django.test import TestCase from django.test.client import RequestFactory from rest_framework import generics, status, serializers from rest_framework.tests.models import Anchor, BasicModel, ManyToManyModel, BlogPost, BlogPostComment, Album, Photo, OptionalRelationModel +import json factory = RequestFactory() @@ -71,7 +72,7 @@ class AlbumDetail(generics.RetrieveAPIView): model = Album -class OptionalRelationDetail(generics.RetrieveAPIView): +class OptionalRelationDetail(generics.RetrieveUpdateDestroyAPIView): model = OptionalRelationModel model_serializer_class = serializers.HyperlinkedModelSerializer @@ -247,3 +248,12 @@ class TestOptionalRelationHyperlinkedView(TestCase): response = self.detail_view(request, pk=1).render() self.assertEquals(response.status_code, status.HTTP_200_OK) self.assertEquals(response.data, self.data) + + def test_put_detail_view(self): + """ + PUT requests to RetrieveUpdateDestroyAPIView with optional relations + should accept None for non existing relations. + """ + # Using the factory, the None incorrectly becomes u'None'. Use the normal test client instead + response = self.client.put('/optionalrelation/1/', data=json.dumps(self.data), content_type='application/json') + self.assertEqual(response.status_code, status.HTTP_200_OK)