47 lines
1.9 KiB
Python
47 lines
1.9 KiB
Python
from django.core.urlresolvers import NoReverseMatch
|
|
from rest_framework.reverse import reverse
|
|
from rest_framework.routers import replace_methodname
|
|
|
|
|
|
def link_wrap(view, view_names):
|
|
def wrapper(self, request, view=view, *args, **kwargs):
|
|
""" wrapper function that inserts HTTP links on view """
|
|
links = []
|
|
for name in view_names:
|
|
try:
|
|
url = reverse(name, request=self.request)
|
|
except NoReverseMatch:
|
|
url = reverse(name, args, kwargs, request=request)
|
|
links.append('<%s>; rel="%s"' % (url, name))
|
|
response = view(self, request, *args, **kwargs)
|
|
response['Link'] = ', '.join(links)
|
|
return response
|
|
for attr in dir(view):
|
|
try:
|
|
setattr(wrapper, attr, getattr(view, attr))
|
|
except:
|
|
pass
|
|
return wrapper
|
|
|
|
|
|
def insert_links(viewset, base_name):
|
|
collection_links = ['api-root', '%s-list' % base_name]
|
|
object_links = ['api-root', '%s-list' % base_name, '%s-detail' % base_name]
|
|
exception_links = ['api-root']
|
|
list_links = ['api-root']
|
|
retrieve_links = ['api-root', '%s-list' % base_name]
|
|
# Determine any `@action` or `@link` decorated methods on the viewset
|
|
for methodname in dir(viewset):
|
|
method = getattr(viewset, methodname)
|
|
view_name = '%s-%s' % (base_name, methodname.replace('_', '-'))
|
|
if hasattr(method, 'collection_bind_to_methods'):
|
|
list_links.append(view_name)
|
|
retrieve_links.append(view_name)
|
|
setattr(viewset, methodname, link_wrap(method, collection_links))
|
|
elif hasattr(method, 'bind_to_methods'):
|
|
retrieve_links.append(view_name)
|
|
setattr(viewset, methodname, link_wrap(method, object_links))
|
|
viewset.handle_exception = link_wrap(viewset.handle_exception, exception_links)
|
|
viewset.list = link_wrap(viewset.list, list_links)
|
|
viewset.retrieve = link_wrap(viewset.retrieve, retrieve_links)
|