Adding more views to a Router or viewset (Django-Rest-Framework)

后端 未结 4 544
既然无缘
既然无缘 2021-02-05 04:48

Essentially, I\'m trying to find a good way to attach more views to a Router without creating a custom Router. What\'s a good way to accomplish this?

He

相关标签:
4条回答
  • 2021-02-05 05:01

    You can now do this with the list_route and detail_route decorators: http://www.django-rest-framework.org/api-guide/viewsets/#marking-extra-actions-for-routing

    For example:

    from rest_framework.decorators import list_route
    from rest_framework.response import Response
    ...
    
    class MyObjectsViewSet(viewsets.ViewSet):
        ...
    
        @list_route()
        def locations(self, request):
            queryset = get_locations()
            serializer = LocationSerializer(queryset, many=True)
            return Response(serializer.data)
    
    0 讨论(0)
  • 2021-02-05 05:07

    From Routing to extra methods on a ViewSet:

    I think you may need to route the method by hand, i.e. The Old-Fashioned Way™.

    First pull the method out as a separate view:

       set_password_view = UserViewSet.as_view({'post': 'set_password'})
    

    (or such)

    Then assign your URL:

       url(r'^users/username_available/$', set_password_view, name-=...)
    

    (Or such)

    There's a related question on SO.

    0 讨论(0)
  • 2021-02-05 05:10

    You define method like you do now, but you need to use the same url as method name and add link decorator, so for

    /myobjects/123/locations/
    

    You add method like this

    @link(permission_classes=[...])
    def locations(self, request, pk=None):
        ...
    

    and router will pick it automatically.

    0 讨论(0)
  • 2021-02-05 05:19

    The answer given by mariodev above is correct, as long as you're only looking to make GET requests.

    If you want to POST to a function you're appending to a ViewSet, you need to use the action decorator:

    from rest_framework.decorators import action, link
    from rest_framework.response import Response
    
    class MyObjectsViewSet(viewsets.ViewSet):
    
        # For GET Requests
        @link()
        def get_locations(self, request):
            """ Returns a list of location objects somehow related to MyObject """
            locations = calculate_something()
            return Response(locations)
    
        # For POST Requests
        @action()
        def update_location(self, request, pk):
            """ Updates the object identified by the pk """
            location = self.get_object()
            location.field = update_location_field() # your custom code
            location.save()
    
            # ...create a serializer and return with updated data...
    

    Then you would POST to a URL formatted like: /myobjects/123/update_location/

    http://www.django-rest-framework.org/api-guide/viewsets/#marking-extra-actions-for-routing has more information if you're interested!

    0 讨论(0)
提交回复
热议问题