2015-05-05 16 views
10

Tôi đang sử dụng khung công tác REST Django, và tôi đã thiết lập chế độ xem với phương thức tuyến danh sách bổ sung. Làm thế nào tôi có thể nhận được URL của phương thức đó trong trang gốc API?Bao gồm các phương thức list_route trong gốc API của khung công tác REST của Django

Dưới đây là một phiên bản đơn giản của bộ quan điểm của tôi:

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) 

tôi đăng ký xem thiết lập trong urls.py:

router = DefaultRouter() 
router.register('books', BookViewSet) 
urlpatterns = patterns(
    url(r'^api/', include(router.urls), name='api_home'), 
    #... 
    ) 

URL cho books/featured được định tuyến đúng, nhưng khi tôi đi đến http://localhost:8000/api, Tôi chỉ thấy điều này:

HTTP 200 OK 
Content-Type: application/json 
Vary: Accept 
Allow: GET, HEAD, OPTIONS 

{ 
    "books": "http://localhost:8000/api/books/" 
} 

Làm thế nào tôi có thể nhận được một mục nhập cho một cái gì đó như thế này?

"book-featured-list": "http://localhost:8000/api/books/featured" 
+0

Có vẻ như con đường để làm điều này là với một [Router tùy chỉnh] (http://www.django-rest-framework.org/api -guide/routers/# custom-routers) và có thể ghi đè phương thức 'get_api_root_view()' của ['DefaultRouter'] (https://github.com/tomchristie/django-rest-framework/blob/4e5da16961c8f11d01a2f9dc475efacb29e778c7/rest_framework/ routers.py # L273). –

Trả lời

2

Bạn có thể cố gắng để kế thừa từ DefaultRouter mà có trách nhiệm xem gốc api và xác định lại phương pháp 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. xin lỗi, không thấy bình luận của bạn trước khi tôi đăng câu trả lời

+0

Nhận xét của tôi chỉ là một gợi ý mơ hồ, cảm ơn vì đã ăn thịt nó. –

+0

Thực ra, tôi đã hy vọng sử dụng trang trí '@ list_route' để khám phá tất cả các tuyến tùy chỉnh thay vì phải liệt kê chúng một cách rõ ràng. Tôi sẽ xem xét 'SimpleRouter' để xem liệu tôi có thể tìm ra cách để thêm vào đó hay không. –

-1

Bạn có thể thử với, đặt dưới url mẫu của bạn. url của bạn sẽ như thế này:

http://localhost:8000/api/books/ 

from rest_framework.urlpatterns import format_suffix_patterns 

urlpatterns = format_suffix_patterns(urlpatterns) 
+0

Cảm ơn bạn đã gợi ý, nhưng [tài liệu] (http://www.django-rest-framework.org/api-guide/format-suffixes/) nói rằng 'format_suffix_patterns' cho phép bạn sử dụng hậu tố để chỉ định định dạng phản hồi thay vì sử dụng tiêu đề HTTP. Ví dụ: tôi có thể yêu cầu '/ api/books.json' hoặc'/api/books.html'. Tôi cũng đã thử nó, và thấy không có mục mới trong trang '/ api'. –

2

Bạn có thể cài đặt gói django-nghỉ ngơi-vênh vang, chỉ cần làm theo ở đây: https://github.com/marcgibbons/django-rest-swagger

Đó là mạnh hơn trang danh sách api DRF của. Nó sẽ liệt kê tất cả các apis còn lại (bao gồm list_route/detail_route apis) cho các mô đun của bạn, và bạn cũng có thể thực hiện một số kiểm tra api (CRUD) trên trang.

+1

Lưu ý rằng [câu trả lời chỉ có liên kết] (http://meta.stackoverflow.com/tags/link-only-answers/info) không được khuyến khích, các câu trả lời SO phải là điểm cuối của việc tìm kiếm giải pháp (so với nhưng một điểm dừng khác của tài liệu tham khảo, mà có xu hướng để có được cũ theo thời gian). Vui lòng xem xét thêm bản tóm tắt độc lập tại đây, giữ liên kết dưới dạng tham chiếu. – kleopatra

0

tôi sử dụng giải pháp này dựa trên câu trả lời của 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) 
Các vấn đề liên quan