openwisp / django-rest-framework-gis

Geographic add-ons for Django REST Framework. Maintained by the OpenWISP Project.
http://openwisp.org
MIT License
1.07k stars 200 forks source link

Filter button not shown with GeoJsonPagination #252

Open LAPAN-fauzan opened 3 years ago

LAPAN-fauzan commented 3 years ago

When GeoJsonPagination is used, the filter button disappear from the API view. The filter button will appear if I use other pagination class.

Here is my current environment configuration `

Django 3.1.4
Django Rest Framework 3.12.2
Django Rest Framework-gis 0.16
Django-filter 2.4.0

` This problem exist from when I started using DRF-gis about one year ago, but I forgot about my environment configuration at that time

Workaround that I found is to copy the existing GeoJsonPagination class as a custom pagination class, then add "results" field into the get_paginated_response function. Somehow "results" field must exist for the filter button to be shown. The filtering itself still works when the filter button is hidden.

`

class CustomPagination(PageNumberPagination):
    page_size = 10
    page_size_query_param = "page_size"
    max_page_size = 1000

    def get_paginated_response(self, data):
        return Response(
              OrderedDict(
                  [
                      ("type", "FeatureCollection"),
                      ("count", self.page.paginator.count),
                      ("next", self.get_next_link()),
                      ("previous", self.get_previous_link()),
                      ("results", ""),
                      ("features", data["features"]),
                  ]
              )
          )
      )

`

nasir733 commented 2 years ago

hi I am facing the same issue but even after adding results it is not working do you have any idea why its not working

catplanck commented 2 years ago

hi I am facing the same issue but even after adding results it is not working do you have any idea why its not working

this is the new code that works (for me at least) `

from collections import OrderedDict
from rest_framework.response import Response
from rest_framework_gis.pagination import GeoJsonPagination

class CustomPagination(GeoJsonPagination):
    def get_paginated_response(self, data):
        return Response(
            OrderedDict(
                [
                    ("type", "FeatureCollection"),
                    ("count", self.page.paginator.count),
                    ("next", self.get_next_link()),
                    ("previous", self.get_previous_link()),
                    ("features", data["features"]),
                    # You can change "" into anything you want, as long as results variable is in the response it should work
                    ("results", ""),
                ]
            )
        )

    def get_paginated_response_schema(self, view):
        schema = super().get_paginated_response_schema(view)
        schema["properties"]["features"] = schema["properties"].pop("results")
        schema["properties"] = {
        "type": {"type": "string", "enum": ["FeatureCollection"]},
             **schema["properties"],
         }
         return schema

`

Add that pagination class into your ViewSets, for example:

`

class TestViewSets(viewsets.ReadOnlyModelViewSet):
    queryset = TestModel.objects.all()
    serializer_class = TestModelSerializer
    filter_backends = [DjangoFilterBackend]
    filterset_fields = [
        "name",
    ]
    pagination_class = CustomPagination

`

The downside of this workaround is you will have empty results variable in your API response, because your data is not presented in results but in features instead. Ex:

`

{
    "type": "FeatureCollection",
    "count": 1,
    "next": null,
    "previous": null,
    "features": [
        {
                <data>
        },
    ],
    "results": ""
}

`

I am not sure if there is a better way to do this.