djangoserializationdjango-rest-frameworkgisgeodjango

How to create a serializer for a GIS Point to use with Django Rest Framework


I've created an endpoint that will return some serialized models (available and unavailable) and a couple of geographic points (sw and ne) that define the bounding box around those models. I'll determine the extents of all of the Listings returned and will defined sw and ne accordingly.

I'd like to do something like this:

class ListingSerializer(serializers.ModelSerializer):
    photos = ListingPhotoSerializer(many=True, read_only=True)

    class Meta:
        model = Listing
        exclude = []


class ListingAvailabilityBBoxSerializer(serializers.Serializer):
    available = ListingSerializer(many=True, read_only=True)
    unavailable = ListingSerializer(many=True, read_only=True)
    sw = PointSerializer(read_only=True)
    ne = PointSerializer(read_only=True)

But PointSerializer for Point (as defined in django.contrib.gis.geos) doesn't exist, as far as I know. Is there a PointSerializer I haven't yet found? How can I do this?


Solution

  • I came up with something that works best for me. At first I tried installing the drf-extra-fields package and creating a serializer like so:

    from drf_extra_fields.geo_fields import PointField
    
    class PointFieldSerializer(serializers.Serializer):
        point = PointField()
    

    That worked as far as I tested, but it didn't play well with drf-spectacular, which I'm using for documentation. Plus it serializes points slightly differently that the model.PointFields that were already in my existing models.

    The best solution for me was to create a Model just for the purposes of creating a model-based serializer. I set managed to False so it wouldn't create a table in the database.

    class PointModel(models.Model):
        point = models.PointField(srid=4326)
    
        class Meta:
            managed = False
    
    
    class PointFieldSerializer(serializers.ModelSerializer):
        class Meta:
            model = PointModel
            fields = ["point"]