mirror of
				https://github.com/encode/django-rest-framework.git
				synced 2025-11-04 18:08:03 +03:00 
			
		
		
		
	Handle reversal of non-API view_name in HyperLinkedRelatedField
This commit is contained in:
		
							parent
							
								
									e34e0536b1
								
							
						
					
					
						commit
						90280a3437
					
				| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
# coding: utf-8
 | 
			
		||||
from __future__ import unicode_literals
 | 
			
		||||
from django.utils.translation import ugettext_lazy as _
 | 
			
		||||
from django.core.urlresolvers import NoReverseMatch
 | 
			
		||||
from rest_framework import exceptions
 | 
			
		||||
from rest_framework.compat import unicode_http_header
 | 
			
		||||
from rest_framework.reverse import _reverse
 | 
			
		||||
| 
						 | 
				
			
			@ -122,7 +123,16 @@ class NamespaceVersioning(BaseVersioning):
 | 
			
		|||
 | 
			
		||||
    def reverse(self, viewname, args=None, kwargs=None, request=None, format=None, **extra):
 | 
			
		||||
        if request.version is not None:
 | 
			
		||||
            viewname = self.get_versioned_viewname(viewname, request)
 | 
			
		||||
            versioned_viewname = self.get_versioned_viewname(viewname, request)
 | 
			
		||||
            try:
 | 
			
		||||
                return super(NamespaceVersioning, self).reverse(
 | 
			
		||||
                    versioned_viewname, args, kwargs, request, format, **extra
 | 
			
		||||
                )
 | 
			
		||||
            except NoReverseMatch:
 | 
			
		||||
                # If the versioned viewname lookup fails, fallback to the
 | 
			
		||||
                # default reversal, since it may be a non-API view
 | 
			
		||||
                pass
 | 
			
		||||
 | 
			
		||||
        return super(NamespaceVersioning, self).reverse(
 | 
			
		||||
            viewname, args, kwargs, request, format, **extra
 | 
			
		||||
        )
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,6 +7,7 @@ from rest_framework.response import Response
 | 
			
		|||
from rest_framework.reverse import reverse
 | 
			
		||||
from rest_framework.test import APIRequestFactory, APITestCase
 | 
			
		||||
from rest_framework.versioning import NamespaceVersioning
 | 
			
		||||
from rest_framework.relations import PKOnlyObject
 | 
			
		||||
import pytest
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -234,7 +235,7 @@ class TestInvalidVersion:
 | 
			
		|||
 | 
			
		||||
class TestHyperlinkedRelatedField(UsingURLPatterns, APITestCase):
 | 
			
		||||
    included = [
 | 
			
		||||
        url(r'^namespaced/(?P<pk>\d+)/$', dummy_view, name='namespaced'),
 | 
			
		||||
        url(r'^namespaced/(?P<pk>\d+)/$', dummy_pk_view, name='namespaced'),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    urlpatterns = [
 | 
			
		||||
| 
						 | 
				
			
			@ -262,3 +263,44 @@ class TestHyperlinkedRelatedField(UsingURLPatterns, APITestCase):
 | 
			
		|||
        assert self.field.to_internal_value('/v1/namespaced/3/') == 'object 3'
 | 
			
		||||
        with pytest.raises(serializers.ValidationError):
 | 
			
		||||
            self.field.to_internal_value('/v2/namespaced/3/')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
class TestNamespaceVersioningHyperlinkedRelatedFieldScheme(UsingURLPatterns, APITestCase):
 | 
			
		||||
    included = [
 | 
			
		||||
        url(r'^namespaced/(?P<pk>\d+)/$', dummy_pk_view, name='namespaced'),
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    urlpatterns = [
 | 
			
		||||
        url(r'^v1/', include(included, namespace='v1')),
 | 
			
		||||
        url(r'^v2/', include(included, namespace='v2')),
 | 
			
		||||
        url(r'^non-api/(?P<pk>\d+)/$', dummy_pk_view, name='non-api-view')
 | 
			
		||||
    ]
 | 
			
		||||
 | 
			
		||||
    def _create_field(self, view_name, version):
 | 
			
		||||
        request = factory.get("/")
 | 
			
		||||
        request.versioning_scheme = NamespaceVersioning()
 | 
			
		||||
        request.version = version
 | 
			
		||||
 | 
			
		||||
        field = serializers.HyperlinkedRelatedField(
 | 
			
		||||
            view_name=view_name,
 | 
			
		||||
            read_only=True)
 | 
			
		||||
        field._context = {'request': request}
 | 
			
		||||
        return field
 | 
			
		||||
 | 
			
		||||
    def test_api_url_is_properly_reversed_with_v1(self):
 | 
			
		||||
        field = self._create_field('namespaced', 'v1')
 | 
			
		||||
        assert field.to_representation(PKOnlyObject(3)) == 'http://testserver/v1/namespaced/3/'
 | 
			
		||||
 | 
			
		||||
    def test_api_url_is_properly_reversed_with_v2(self):
 | 
			
		||||
        field = self._create_field('namespaced', 'v2')
 | 
			
		||||
        assert field.to_representation(PKOnlyObject(5)) == 'http://testserver/v2/namespaced/5/'
 | 
			
		||||
 | 
			
		||||
    def test_non_api_url_is_properly_reversed_regardless_of_the_version(self):
 | 
			
		||||
        """
 | 
			
		||||
        Regression test for #2711
 | 
			
		||||
        """
 | 
			
		||||
        field = self._create_field('non-api-view', 'v1')
 | 
			
		||||
        assert field.to_representation(PKOnlyObject(10)) == 'http://testserver/non-api/10/'
 | 
			
		||||
 | 
			
		||||
        field = self._create_field('non-api-view', 'v2')
 | 
			
		||||
        assert field.to_representation(PKOnlyObject(10)) == 'http://testserver/non-api/10/'
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue
	
	Block a user