Documentation of "extra link and actions" via rest-swagger and CoreApi

68 views
Skip to first unread message

Alfredo Branco

unread,
Oct 21, 2016, 7:55:55 AM10/21/16
to Django REST framework
Hello everyone!

As stated in the subject I need to document an extra action of a ModelViewset using django 1.9.7 and DRF 3.5.0 plus the latest version of the requirements.
I was able to get it in the way that I'm going to explain, but I was wondering if there is a more "correct" way to do this

I have a class like this:

...

import django_filters
import django_filters.rest_framework as filters_drf
from rest_framework import filters

class MyModelSerializer(serializers.ModelSerializer):
    id = serializers.PrimaryKeyRelatedField(many=False, read_only=True)
    class Meta:
        model = models.MyModel
        fields = '__all__'

class MyModelFilter(filters_drf.FilterSet):
    day_gte = django_filters.DateFilter(name="day", lookup_expr='gte')
    day_lte = django_filters.DateFilter(name="day", lookup_expr='lte')

class MyModelViewSet(viewsets.ReadOnlyModelViewSet):
    queryset
= models.MyModel.objects.all()
    serializer_class
= MyModelSerializer
    filter_class
= MyModelFilter
    filter_backends
= (filters.DjangoFilterBackend, filters.OrderingFilter, filters.SearchFilter,)


   
@list_route()
   
def my_new_action(self, request):
       
"""
        Some descriptive info        
        """

        queryset
= self.filter_queryset(self.get_queryset())
       
       
if queryset.count() > MAX_GRAPH_POINT:
           
raise NotAcceptable(_("Query returned too much data. Please apply a filter"))
       
       resultset
= do_some_stuff_on(queryset)
       
return Response(resultset)


To make DRF to recognize the extra action my_new_action as a list view I have modified the is_list_view function in rest_framework/schemas.py in this way

def is_list_view(path, method, view):
   
"""
    Return True if the given path/method appears to represent a list view.
    """

   
if hasattr(view, 'action'):
       
if hasattr(view, 'detail'):
           
return not view.detail
       
else:
           
# Viewsets have an explicitly defined action, which we can inspect.
           
if view.action == 'list':
               
return True

   
if method.lower() != 'get':
       
return False
    path_components
= path.strip('/').split('/')
   
if path_components and '{' in path_components[-1]:
       
return False
   
return True


the code is a quick and dirty fix because the original version does not recognize the my_new_action as a list view.

Does anyone know a better and more standard way to do it?

Thank you.

Alfredo
Reply all
Reply to author
Forward
0 new messages