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