django-rest-framework-gis icon indicating copy to clipboard operation
django-rest-framework-gis copied to clipboard

Allow geo_field to be an annotated field

Open henhuy opened this issue 4 years ago • 2 comments

I have a model with a geom (srid=3035) and I want to serialize it as geom (srid=4326). Did not found a solution to do this with django-restframework-gis? My approach was:

from django.contrib.gis.db.models.functions import Transform

class TransformManager(models.Manager):
    def get_queryset(self):
        return super().get_queryset().annotate(geom_4326=Transform("geom", 4326))

class State(models.Model):
    id = models.BigIntegerField(primary_key=True)
    name = models.CharField(max_length=60)
    geom = models.MultiPolygonField(srid=3035)

    objects = TransformManager()

class StatesSerializer(GeoFeatureModelSerializer):
    class Meta:
        model = State
        geo_field = "geom_4326"
        fields = [
            "id",
            "name",
            "geom_4326"
        ]

class StatesListAPIView(ListAPIView):
    queryset = State.objects.all()
    serializer_class = StatesSerializer
    lookup_field = 'id'

but this gives me: django.core.exceptions.ImproperlyConfigured: Field name geom_4326is not valid for modelState.

Also found this: https://stackoverflow.com/questions/22449406/how-to-transform-geometry-in-django-rest-framework-gis/22537247#22537247 But couldn't get it to work... (see my comment on that answer)

Any help? thx

henhuy avatar Nov 17 '20 14:11 henhuy

Try this (using GeometrySerializerMethodField):

class InSituCommentSerializer(GeoFeatureModelSerializer):
    geometry_4326 = GeometrySerializerMethodField()

    def get_geometry_4326(self, state) -> Polygon:
        return state.geom.transform(4326, clone=True)

    class Meta:
        model = Instance
        geo_field = "geometry_4326"
        fields = ("name", )

StefanBrand avatar Jun 25 '21 12:06 StefanBrand

Other solution that is cleaner in my opinion because it uses db for transformation:


class StatesSerializer(GeoFeatureModelSerializer):
    geom_4326 = GeometryField()

    class Meta:
        model = State
        geo_field = "geom_4326"
        fields = [
            "id",
            "name",
            "geom_4326"
        ]

a-gorski-aic avatar Mar 03 '22 12:03 a-gorski-aic