mirror of
				https://github.com/encode/django-rest-framework.git
				synced 2025-11-04 01:47:59 +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.query import QuerySet
 | 
			
		||||
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.translation import ugettext_lazy as _
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -324,6 +326,8 @@ class HyperlinkedRelatedField(RelatedField):
 | 
			
		|||
            if data.startswith(prefix):
 | 
			
		||||
                data = '/' + data[len(prefix):]
 | 
			
		||||
 | 
			
		||||
        data = uri_to_iri(data)
 | 
			
		||||
 | 
			
		||||
        try:
 | 
			
		||||
            match = resolve(data)
 | 
			
		||||
        except Resolver404:
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,9 @@
 | 
			
		|||
import uuid
 | 
			
		||||
 | 
			
		||||
import pytest
 | 
			
		||||
from django.conf.urls import url
 | 
			
		||||
from django.core.exceptions import ImproperlyConfigured
 | 
			
		||||
from django.test import override_settings
 | 
			
		||||
from django.utils.datastructures import MultiValueDict
 | 
			
		||||
 | 
			
		||||
from rest_framework import serializers
 | 
			
		||||
| 
						 | 
				
			
			@ -87,10 +89,21 @@ class TestProxiedPrimaryKeyRelatedField(APISimpleTestCase):
 | 
			
		|||
        assert representation == self.instance.pk.int
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@override_settings(ROOT_URLCONF=[
 | 
			
		||||
    url(r'^example/(?P<name>.+)/$', lambda: None, name='example'),
 | 
			
		||||
])
 | 
			
		||||
class TestHyperlinkedRelatedField(APISimpleTestCase):
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        self.queryset = MockQueryset([
 | 
			
		||||
            MockObject(pk=1, name='foobar'),
 | 
			
		||||
            MockObject(pk=2, name='baz qux'),
 | 
			
		||||
        ])
 | 
			
		||||
        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._context = {'request': True}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -98,6 +111,20 @@ class TestHyperlinkedRelatedField(APISimpleTestCase):
 | 
			
		|||
        representation = self.field.to_representation(MockObject(pk=''))
 | 
			
		||||
        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):
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -156,6 +156,7 @@ class TestCustomLookupFields(TestCase):
 | 
			
		|||
    """
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
        RouterTestModel.objects.create(uuid='123', text='foo bar')
 | 
			
		||||
        RouterTestModel.objects.create(uuid='a b', text='baz qux')
 | 
			
		||||
 | 
			
		||||
    def test_custom_lookup_field_route(self):
 | 
			
		||||
        detail_route = notes_router.urls[-1]
 | 
			
		||||
| 
						 | 
				
			
			@ -164,12 +165,19 @@ class TestCustomLookupFields(TestCase):
 | 
			
		|||
 | 
			
		||||
    def test_retrieve_lookup_field_list_view(self):
 | 
			
		||||
        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):
 | 
			
		||||
        response = self.client.get('/example/notes/123/')
 | 
			
		||||
        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):
 | 
			
		||||
    """
 | 
			
		||||
| 
						 | 
				
			
			@ -211,6 +219,10 @@ class TestLookupUrlKwargs(TestCase):
 | 
			
		|||
        response = self.client.get('/example2/notes/fo/')
 | 
			
		||||
        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):
 | 
			
		||||
    def setUp(self):
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user