wq / django-rest-pandas

📊📈 Serves up Pandas dataframes via the Django REST Framework for use in client-side (i.e. d3.js) visualizations and offline analysis (e.g. Excel)

Home Page:https://django-rest-pandas.wq.io/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Response data is a ReturnList, not a DataFrame! Did you extend PandasMixin?

pinkynrg opened this issue · comments

I really would love to use this nice package but I'm getting this error no matter what I do.

I see that no one is really maintaining this package anymore but I really hope someone may clarify this for me.

  1. Added 'rest_pandas' in installed app BEFORE 'rest_framework'
  2. Added 'rest_pandas.renderers.PandasExcelRenderer' in DEFAULT_RENDERED_CLASS
  3. I see an xlsx selectable option in the api django rest framework view
  4. Added PandasMixin to my BaseView
  5. Response data is a ReturnList, not a DataFrame! Did you extend PandasMixin?

Following my baseApi view:

class BaseApi(mixins.RetrieveModelMixin,
              mixins.ListModelMixin,
              mixins.UpdateModelMixin,
              mixins.DestroyModelMixin,
              PandasMixin,
              BulkCreateModelMixin,
              BulkUpdateModelMixin,
              generics.GenericAPIView):

    filter_backends = (OrderingFilter, SearchFilter, DjangoFilterBackend)
    pagination_class = StandardResultsSetPagination

    def get_list(self, request, *args, **kwargs):

        queryset = self.filter_queryset(self.get_queryset())

        page = self.paginate_queryset(queryset)

        if page is not None:
            serializer = self.get_serializer(page, many=True)
            response = self.get_paginated_response(serializer.data)
        else:
            serializer = self.get_serializer(queryset, many=True)
            response = Response(serializer.data)

        query = {
            "ordering_fields": [],
            "filter_fields": [],
            "search_fields": [],
            "element_count": len(response.data),
            "element_total_count": queryset.count(),
            "previous_page": self.paginator.get_previous_link(),
            "next_page": self.paginator.get_next_link(),
            "page_count": self.paginator.page.paginator.num_pages,
            "current_page_size": self.paginator.get_page_size(request),
            "current_page": self.paginator.page.number,
            "max_page_size": self.paginator.max_page_size,
        }

        for backend in list(self.filter_backends):
            if isinstance(backend(), OrderingFilter):
                query["ordering_fields"] = backend().get_ordering(
                    request=self.request,
                    queryset=self.queryset.all(),
                    view=self
                ) or []
            elif isinstance(backend(), SearchFilter):
                query["search_fields"] = backend().get_search_terms(request)
            elif isinstance(backend(), DjangoFilterBackend):
                for f in self.request.query_params.keys():
                    if hasattr(self, 'filter_fields'):
                        if f in self.filter_fields:
                            query["filter_fields"].append({f: self.request.query_params[f]})
                    elif hasattr(self, 'filter_class'):
                        if f in self.filter_class.Meta.fields:
                            query["filter_fields"].append({f: self.request.query_params[f]})

        for k, v in query.items():
            response[k.replace("_", " ").title().replace(" ", "-")] = json.dumps(v)

        if "debug" in self.request.query_params.keys() and self.request.query_params["debug"] == "true":
            response.data = {
                "query": query,
                "data": response.data,
            }

        return response

    # API BASE VIEWS ###########################
    def get(self, request, *args, **kwargs):
        if 'pk' in kwargs.keys():
            return self.retrieve(request, *args, **kwargs)
        else:
            return self.get_list(request, *args, **kwargs)

    def put(self, request, *args, **kwargs):
        if 'pk' in kwargs.keys():
            return self.update(request, partial=True)
        else:
            return self.partial_bulk_update(request, *args, **kwargs)

    def delete(self, request, *args, **kwargs):
        return self.destroy(request, *args, **kwargs)

    def post(self, request, *args, **kwargs):
        return self.create(request, *args, **kwargs)
    # END API BASE VIEWS #######################

@pinkynrg, try add to yours serializer:

from rest_pandas.serializers import PandasSerializer

class YourSerializer(serializers.ModelSerializer):

    class Meta:
        model = YourModel
        list_serializer_class = PandasSerializer

This solved the same problem for me!

Thanks, yes the list_serializer_class is the key component. I updated the README as well.