mirror of
https://github.com/encode/django-rest-framework.git
synced 2025-08-05 04:50:12 +03:00
Merge 4ba48d3460
into e4c7c10b00
This commit is contained in:
commit
56f329fbe6
|
@ -140,6 +140,17 @@ As with `SimpleRouter` the trailing slashes on the URL routes can be removed by
|
|||
|
||||
router = DefaultRouter(trailing_slash=False)
|
||||
|
||||
If you wish to put the router namespace, you will need to pass the `namespace` name to `DefaultRouter`.
|
||||
|
||||
router = DefaultRouter(namespace='api')
|
||||
urlpatterns = [
|
||||
url(r'^', include(router.urls, namespace='api')),
|
||||
]
|
||||
|
||||
Please note if you do this, you will have to specify your namespace in your serializers too.
|
||||
|
||||
url = serializers.HyperlinkedIdentityField(view_name='api:mymodel-detail')
|
||||
|
||||
# Custom Routers
|
||||
|
||||
Implementing a custom router isn't something you'd need to do very often, but it can be useful if you have specific requirements about how the your URLs for your API are structured. Doing so allows you to encapsulate the URL structure in a reusable way that ensures you don't have to write your URL patterns explicitly for each new view.
|
||||
|
|
|
@ -278,6 +278,10 @@ class DefaultRouter(SimpleRouter):
|
|||
include_format_suffixes = True
|
||||
root_view_name = 'api-root'
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.namespace = kwargs.pop('namespace', None)
|
||||
super(DefaultRouter, self).__init__(*args, **kwargs)
|
||||
|
||||
def get_api_root_view(self):
|
||||
"""
|
||||
Return a view to use as the API root.
|
||||
|
@ -287,12 +291,16 @@ class DefaultRouter(SimpleRouter):
|
|||
for prefix, viewset, basename in self.registry:
|
||||
api_root_dict[prefix] = list_name.format(basename=basename)
|
||||
|
||||
namespace = self.namespace
|
||||
|
||||
class APIRoot(views.APIView):
|
||||
_ignore_model_permissions = True
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
ret = OrderedDict()
|
||||
for key, url_name in api_root_dict.items():
|
||||
if namespace:
|
||||
url_name = '%s:%s' % (namespace, url_name)
|
||||
try:
|
||||
ret[key] = reverse(
|
||||
url_name,
|
||||
|
|
32
tests/namespaced_urls.py
Normal file
32
tests/namespaced_urls.py
Normal file
|
@ -0,0 +1,32 @@
|
|||
from django.conf.urls import url, include
|
||||
from django.db import models
|
||||
|
||||
from rest_framework import serializers, viewsets, routers
|
||||
|
||||
|
||||
class NamespacedRouterTestModel(models.Model):
|
||||
uuid = models.CharField(max_length=20)
|
||||
text = models.CharField(max_length=200)
|
||||
|
||||
|
||||
class NoteSerializer(serializers.HyperlinkedModelSerializer):
|
||||
url = serializers.HyperlinkedIdentityField(view_name='api-namespace:routertestmodel-detail', lookup_field='uuid')
|
||||
|
||||
class Meta:
|
||||
model = NamespacedRouterTestModel
|
||||
fields = ('url', 'uuid', 'text')
|
||||
|
||||
|
||||
class NoteViewSet(viewsets.ModelViewSet):
|
||||
queryset = NamespacedRouterTestModel.objects.all()
|
||||
serializer_class = NoteSerializer
|
||||
lookup_field = 'uuid'
|
||||
|
||||
router = routers.DefaultRouter(namespace='api-namespace')
|
||||
|
||||
router.register(r'note', NoteViewSet)
|
||||
|
||||
|
||||
urlpatterns = [
|
||||
url('^namespaced-api/', include(router.urls, namespace='api-namespace')),
|
||||
]
|
|
@ -321,3 +321,13 @@ class TestRootWithAListlessViewset(TestCase):
|
|||
request = factory.get('/')
|
||||
response = self.view(request)
|
||||
self.assertEqual(response.data, {})
|
||||
|
||||
|
||||
class TestNamespacedDefaultRouter(TestCase):
|
||||
urls = 'tests.namespaced_urls'
|
||||
|
||||
def test_api_root(self):
|
||||
from django.core.urlresolvers import reverse
|
||||
url = reverse('api-namespace:api-root')
|
||||
response = self.client.get(url)
|
||||
self.assertEqual(response.data['note'], 'http://testserver/namespaced-api/note/')
|
||||
|
|
Loading…
Reference in New Issue
Block a user