Skip to content

Custom query params in Swagger #21

@BrianHGrant

Description

@BrianHGrant

Due to depreciation of YAML docstrings in Django Rest Framework (see: marcgibbons/django-rest-swagger#549), the documented procedure for entering query params that are not fields in model no longer works. Through research and trial and error I have been able to create a workaround:

Step 1. Create a custom filter backend with a get_schema_fields method. This method creates an empty array, then defines each param as a coreapi.field. It then appends them to the fields array and returns this array. IE:

class FireBlockGeoFilter(GeoFilterSet):

class Meta:
    model = FireBlock
    fields = []

def get_schema_fields(self, view):
    fields = []
    lat = coreapi.Field(
        name="lat",
        location="query",
        required=True,
        description="Latitude of search point",
        type="number",
        )
    lon = coreapi.Field(
        name="lon",
        location="query",
        required=True,
        description="Longitude of search point",
        type="number",
        )
    fields.append(lat)
    fields.append(lon)
    return fields
  1. This filter is then added to the view as a filter_backend:

filter_backends = (FireBlockGeoFilter,)

The entire view:

class FireBlockGeoFilterViewSet(generics.ListAPIView):

queryset = FireBlock.objects.all
serializer_class = FireBlockSerializer
filter_backends = (FireBlockGeoFilter,)
def get(self, request, *args, **kwargs):
    fireblocks = FireBlock.objects.all
    if request.GET.get('lat', ' ') != ' ' and request.GET.get('lon', ' ') != ' ':
        try:
            lat = float(request.GET.get('lat', ' '))
            lon = float(request.GET.get('lon', ' '))
            pnt = Point(lon, lat, srid=4326)
            fireblocks = FireBlock.objects.filter(geom__contains=pnt)
            if fireblocks:
                serialized_fireblocks = FireBlockSerializer(fireblocks, many=True) # return the serialized fireblock objects
                return Response(serialized_fireblocks.data) #returns to client
            else:
                return Response('No Fireblock found for this latitude and longitude.', status=status.HTTP_404_NOT_FOUND)
        except ValueError:
            return Response('Latitude or longitude is invalid.', status=status.HTTP_404_NOT_FOUND)
    else:
        return Response('Missing latitude or longitude paramater.', status=status.HTTP_400_BAD_REQUEST)

Question: Any better ways to complete this?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions