mirror of
				https://github.com/encode/django-rest-framework.git
				synced 2025-11-04 18:08:03 +03:00 
			
		
		
		
	add URL path unquote to HyperlinkedRelatedField.to_internal_value
This commit is contained in:
		
							parent
							
								
									fd72a814f8
								
							
						
					
					
						commit
						5e185aa26b
					
				| 
						 | 
					@ -7,7 +7,9 @@ from django.core.exceptions import ImproperlyConfigured, ObjectDoesNotExist
 | 
				
			||||||
from django.db.models import Manager
 | 
					from django.db.models import Manager
 | 
				
			||||||
from django.db.models.query import QuerySet
 | 
					from django.db.models.query import QuerySet
 | 
				
			||||||
from django.utils import six
 | 
					from django.utils import six
 | 
				
			||||||
from django.utils.encoding import python_2_unicode_compatible, smart_text
 | 
					from django.utils.encoding import (
 | 
				
			||||||
 | 
					    python_2_unicode_compatible, smart_text, uri_to_iri
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
from django.utils.six.moves.urllib import parse as urlparse
 | 
					from django.utils.six.moves.urllib import parse as urlparse
 | 
				
			||||||
from django.utils.translation import ugettext_lazy as _
 | 
					from django.utils.translation import ugettext_lazy as _
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -324,6 +326,8 @@ class HyperlinkedRelatedField(RelatedField):
 | 
				
			||||||
            if data.startswith(prefix):
 | 
					            if data.startswith(prefix):
 | 
				
			||||||
                data = '/' + data[len(prefix):]
 | 
					                data = '/' + data[len(prefix):]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        data = uri_to_iri(data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            match = resolve(data)
 | 
					            match = resolve(data)
 | 
				
			||||||
        except Resolver404:
 | 
					        except Resolver404:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,7 +1,9 @@
 | 
				
			||||||
import uuid
 | 
					import uuid
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import pytest
 | 
					import pytest
 | 
				
			||||||
 | 
					from django.conf.urls import url
 | 
				
			||||||
from django.core.exceptions import ImproperlyConfigured
 | 
					from django.core.exceptions import ImproperlyConfigured
 | 
				
			||||||
 | 
					from django.test import override_settings
 | 
				
			||||||
from django.utils.datastructures import MultiValueDict
 | 
					from django.utils.datastructures import MultiValueDict
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from rest_framework import serializers
 | 
					from rest_framework import serializers
 | 
				
			||||||
| 
						 | 
					@ -87,10 +89,21 @@ class TestProxiedPrimaryKeyRelatedField(APISimpleTestCase):
 | 
				
			||||||
        assert representation == self.instance.pk.int
 | 
					        assert representation == self.instance.pk.int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@override_settings(ROOT_URLCONF=[
 | 
				
			||||||
 | 
					    url(r'^example/(?P<name>.+)/$', lambda: None, name='example'),
 | 
				
			||||||
 | 
					])
 | 
				
			||||||
class TestHyperlinkedRelatedField(APISimpleTestCase):
 | 
					class TestHyperlinkedRelatedField(APISimpleTestCase):
 | 
				
			||||||
    def setUp(self):
 | 
					    def setUp(self):
 | 
				
			||||||
 | 
					        self.queryset = MockQueryset([
 | 
				
			||||||
 | 
					            MockObject(pk=1, name='foobar'),
 | 
				
			||||||
 | 
					            MockObject(pk=2, name='baz qux'),
 | 
				
			||||||
 | 
					        ])
 | 
				
			||||||
        self.field = serializers.HyperlinkedRelatedField(
 | 
					        self.field = serializers.HyperlinkedRelatedField(
 | 
				
			||||||
            view_name='example', read_only=True)
 | 
					            view_name='example',
 | 
				
			||||||
 | 
					            lookup_field='name',
 | 
				
			||||||
 | 
					            lookup_url_kwarg='name',
 | 
				
			||||||
 | 
					            queryset=self.queryset,
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
        self.field.reverse = mock_reverse
 | 
					        self.field.reverse = mock_reverse
 | 
				
			||||||
        self.field._context = {'request': True}
 | 
					        self.field._context = {'request': True}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -98,6 +111,20 @@ class TestHyperlinkedRelatedField(APISimpleTestCase):
 | 
				
			||||||
        representation = self.field.to_representation(MockObject(pk=''))
 | 
					        representation = self.field.to_representation(MockObject(pk=''))
 | 
				
			||||||
        assert representation is None
 | 
					        assert representation is None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_hyperlinked_related_lookup_exists(self):
 | 
				
			||||||
 | 
					        instance = self.field.to_internal_value('http://example.org/example/foobar/')
 | 
				
			||||||
 | 
					        assert instance is self.queryset.items[0]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_hyperlinked_related_lookup_url_encoded_exists(self):
 | 
				
			||||||
 | 
					        instance = self.field.to_internal_value('http://example.org/example/baz%20qux/')
 | 
				
			||||||
 | 
					        assert instance is self.queryset.items[1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_hyperlinked_related_lookup_does_not_exist(self):
 | 
				
			||||||
 | 
					        with pytest.raises(serializers.ValidationError) as excinfo:
 | 
				
			||||||
 | 
					            self.field.to_internal_value('http://example.org/example/doesnotexist/')
 | 
				
			||||||
 | 
					        msg = excinfo.value.detail[0]
 | 
				
			||||||
 | 
					        assert msg == 'Invalid hyperlink - Object does not exist.'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestHyperlinkedIdentityField(APISimpleTestCase):
 | 
					class TestHyperlinkedIdentityField(APISimpleTestCase):
 | 
				
			||||||
    def setUp(self):
 | 
					    def setUp(self):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -156,6 +156,7 @@ class TestCustomLookupFields(TestCase):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    def setUp(self):
 | 
					    def setUp(self):
 | 
				
			||||||
        RouterTestModel.objects.create(uuid='123', text='foo bar')
 | 
					        RouterTestModel.objects.create(uuid='123', text='foo bar')
 | 
				
			||||||
 | 
					        RouterTestModel.objects.create(uuid='a b', text='baz qux')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_custom_lookup_field_route(self):
 | 
					    def test_custom_lookup_field_route(self):
 | 
				
			||||||
        detail_route = notes_router.urls[-1]
 | 
					        detail_route = notes_router.urls[-1]
 | 
				
			||||||
| 
						 | 
					@ -164,12 +165,19 @@ class TestCustomLookupFields(TestCase):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_retrieve_lookup_field_list_view(self):
 | 
					    def test_retrieve_lookup_field_list_view(self):
 | 
				
			||||||
        response = self.client.get('/example/notes/')
 | 
					        response = self.client.get('/example/notes/')
 | 
				
			||||||
        assert response.data == [{"url": "http://testserver/example/notes/123/", "uuid": "123", "text": "foo bar"}]
 | 
					        assert response.data == [
 | 
				
			||||||
 | 
					            {"url": "http://testserver/example/notes/123/", "uuid": "123", "text": "foo bar"},
 | 
				
			||||||
 | 
					            {"url": "http://testserver/example/notes/a%20b/", "uuid": "a b", "text": "baz qux"},
 | 
				
			||||||
 | 
					        ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def test_retrieve_lookup_field_detail_view(self):
 | 
					    def test_retrieve_lookup_field_detail_view(self):
 | 
				
			||||||
        response = self.client.get('/example/notes/123/')
 | 
					        response = self.client.get('/example/notes/123/')
 | 
				
			||||||
        assert response.data == {"url": "http://testserver/example/notes/123/", "uuid": "123", "text": "foo bar"}
 | 
					        assert response.data == {"url": "http://testserver/example/notes/123/", "uuid": "123", "text": "foo bar"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_retrieve_lookup_field_url_encoded_detail_view_(self):
 | 
				
			||||||
 | 
					        response = self.client.get('/example/notes/a%20b/')
 | 
				
			||||||
 | 
					        assert response.data == {"url": "http://testserver/example/notes/a%20b/", "uuid": "a b", "text": "baz qux"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestLookupValueRegex(TestCase):
 | 
					class TestLookupValueRegex(TestCase):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
| 
						 | 
					@ -211,6 +219,10 @@ class TestLookupUrlKwargs(TestCase):
 | 
				
			||||||
        response = self.client.get('/example2/notes/fo/')
 | 
					        response = self.client.get('/example2/notes/fo/')
 | 
				
			||||||
        assert response.data == {"url": "http://testserver/example/notes/123/", "uuid": "123", "text": "foo bar"}
 | 
					        assert response.data == {"url": "http://testserver/example/notes/123/", "uuid": "123", "text": "foo bar"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def test_retrieve_lookup_url_encoded_kwarg_detail_view(self):
 | 
				
			||||||
 | 
					        response = self.client.get('/example2/notes/foo%20bar/')
 | 
				
			||||||
 | 
					        assert response.data == {"url": "http://testserver/example/notes/123/", "uuid": "123", "text": "foo bar"}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class TestTrailingSlashIncluded(TestCase):
 | 
					class TestTrailingSlashIncluded(TestCase):
 | 
				
			||||||
    def setUp(self):
 | 
					    def setUp(self):
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user