Включить методы list_route в корневой API API Django REST
Я использую структуру Django REST, и у меня есть представление с дополнительным методом маршрута списка. Как я могу получить этот URL метода, включенного в корневую страницу API?
Здесь приведена упрощенная версия моего представления:
class BookViewSet(viewsets.ReadOnlyModelViewSet):
queryset = Book.objects.all()
serializer_class = BookSerializer
permission_classes = (permissions.IsAuthenticated, )
@list_route(methods=['get'])
def featured(self, request):
queryset = self.filter_queryset(self.get_queryset()).filter(featured=True)
page = self.paginate_queryset(queryset)
if page is not None:
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)
serializer = self.get_serializer(queryset, many=True)
return Response(serializer.data)
Я регистрирую представление, установленное в urls.py
:
router = DefaultRouter()
router.register('books', BookViewSet)
urlpatterns = patterns(
url(r'^api/', include(router.urls), name='api_home'),
#...
)
URL для books/featured
маршрутизируется правильно, но когда я перехожу к http://localhost:8000/api
, я вижу только это:
HTTP 200 OK
Content-Type: application/json
Vary: Accept
Allow: GET, HEAD, OPTIONS
{
"books": "http://localhost:8000/api/books/"
}
Как я могу добавить запись для чего-то вроде этого?
"book-featured-list": "http://localhost:8000/api/books/featured"
Ответы
Ответ 1
Вы можете попытаться наследовать от DefaultRouter, который отвечает за корневой вид api и переопределяет метод get_api_root_view.
class MyRouter(routers.DefaultRouter):
def get_api_root_view(self):
"""
Return a view to use as the API root.
"""
api_root_dict = OrderedDict()
list_name = self.routes[0].name
for prefix, viewset, basename in self.registry:
api_root_dict[prefix] = list_name.format(basename=basename)
class APIRoot(views.APIView):
_ignore_model_permissions = True
def get(self, request, *args, **kwargs):
ret = OrderedDict()
namespace = request.resolver_match.namespace
for key, url_name in api_root_dict.items():
if namespace:
url_name = namespace + ':' + url_name
try:
ret[key] = reverse(
url_name,
args=args,
kwargs=kwargs,
request=request,
format=kwargs.get('format', None)
)
except NoReverseMatch:
# Don't bail out if eg. no list routes exist, only detail routes.
continue
ret['book-featured-list'] = '%s%s' % (ret['books'], 'featured/')
return Response(ret)
return APIRoot.as_view()
P.S. извините, не увидели ваш комментарий, прежде чем я отправил ответ
Ответ 2
Вы можете установить пакет django-rest-swagger, просто следуйте ниже: https://github.com/marcgibbons/django-rest-swagger
Он более мощный, чем страница списка api DRF. Он отобразит все остальные apis (include list_route/detail_route apis) для ваших модулей, и вы также можете выполнить некоторые тесты api (CRUD) на странице.
Ответ 3
Я использую это решение на основе ответа likeon:
class MyRouter(routers.DefaultRouter):
def get_api_root_view(self, api_urls=None):
api_root_dict = OrderedDict()
list_name = self.routes[0].name
for prefix, viewset, basename in self.registry:
api_root_dict[prefix] = list_name.format(basename=basename)
api_root_dict['books/featured'] = 'book-featured'
return self.APIRootView.as_view(api_root_dict=api_root_dict)
Ответ 4
Вы можете попробовать, поместите это ниже своих URL-адресов.
Ваш URL будет выглядеть следующим образом:
http://localhost:8000/api/books/
from rest_framework.urlpatterns import format_suffix_patterns
urlpatterns = format_suffix_patterns(urlpatterns)