diff --git a/docs/api-guide/settings.md b/docs/api-guide/settings.md index ea150e10f..38ddb965c 100644 --- a/docs/api-guide/settings.md +++ b/docs/api-guide/settings.md @@ -400,7 +400,7 @@ This should be a function with the following signature: view_name(cls, suffix=None) -* `cls`: The view class. Typically the name function would inspect the name of the class when generating a descriptive name, by accessing `cls.__name__`. +* `cls`: The view class. Typically the name function would inspect the name of the class when generating a descriptive name, by accessing `cls.__name__`. You can set a different name by setting `view_name` variable in your view. * `suffix`: The optional suffix used when differentiating individual views in a viewset. Default: `'rest_framework.views.get_view_name'` diff --git a/rest_framework/views.py b/rest_framework/views.py index f9ee7fb53..b97371e78 100644 --- a/rest_framework/views.py +++ b/rest_framework/views.py @@ -30,7 +30,7 @@ def get_view_name(view_cls, suffix=None): This function is the default for the `VIEW_NAME_FUNCTION` setting. """ - name = view_cls.__name__ + name = view_cls.view_name if hasattr(view_cls, 'view_name') else view_cls.__name__ name = formatting.remove_trailing_string(name, 'View') name = formatting.remove_trailing_string(name, 'ViewSet') name = formatting.camelcase_to_spaces(name) diff --git a/tests/test_utils.py b/tests/test_utils.py index d63f266d6..a5a856846 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -39,6 +39,10 @@ class CustomNameResourceInstance(APIView): return "Foo" +class CustomNameByVariableResourceInstance(APIView): + view_name = "Foo" + + class ResourceViewSet(ModelViewSet): serializer_class = ModelSerializer queryset = BasicModel.objects.all() @@ -50,6 +54,7 @@ urlpatterns = [ url(r'^$', Root.as_view()), url(r'^resource/$', ResourceRoot.as_view()), url(r'^resource/customname$', CustomNameResourceInstance.as_view()), + url(r'^resource/customnamebyvar$', CustomNameByVariableResourceInstance.as_view()), url(r'^resource/(?P[0-9]+)$', ResourceInstance.as_view()), url(r'^resource/(?P[0-9]+)/$', NestedResourceRoot.as_view()), url(r'^resource/(?P[0-9]+)/(?P[A-Za-z]+)$', NestedResourceInstance.as_view()), @@ -88,6 +93,14 @@ class BreadcrumbTests(TestCase): ('Foo', '/resource/customname') ] + def test_resource_instance_customnamebyvar_breadcrumbs(self): + url = '/resource/customname' + assert get_breadcrumbs(url) == [ + ('Root', '/'), + ('Resource Root', '/resource/'), + ('Foo', '/resource/customname') + ] + def test_nested_resource_breadcrumbs(self): url = '/resource/123/' assert get_breadcrumbs(url) == [