Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing a model function to geojson serializer in GeoDjango

Problem description

Ok, I am trying to add a function defined inside a model (called Highway) to the HttpResponse of the model (Highway) after serializing with geojson serializer without success.

I'm trying to find a solution by going through the source code as no errors are passed and the property does not appear in the HttpResponse. I might however be complicating things and hopefully can get another eyes on this. I'm open to other suggestions, maybe to update the Highway each time a Location is added/modified.

The item appears correctly when passing it to the admin site and all other fields (not shown below) work as intended.

PS. I'm quite new to the whole Django system. Thank you!

Django version: 2.1

Relevant links:

  1. https://docs.djangoproject.com/en/2.1/ref/contrib/gis/serializers/
  2. https://github.com/django/django/blob/master/django/contrib/gis/serializers/geojson.py

Minified code

geom.models.py

class Highway(models.Model):

    name = models.CharField(max_length=50, unique=True)
    length = models.IntegerField("Length in meters")
    mline = models.MultiLineStringField("Geometry", srid=4326)

    def cameras_per_km(self):
        #THIS IS THE FUNCTION I AM TRYING TO SEND TO GEOJSON SERIALIZER
        count = self.location_set.filter(location__icontains="camera").count()
        return round(count/(self.length/1000),1)
    cameras_per_km.short_description = "Cameras/km"


class Location(models.Model):

    location = models.CharField(max_length=30, unique=True)
    highway = models.ForeignKey(Highway, null=True, on_delete=models.SET_NULL)
    point = models.PointField()

geom.admin.py (when passing the func to list_display the item appears correclty in admin)

class HighwayAdmin(LeafletGeoAdmin):
    list_display = ('name', 'cameras_per_km')

admin.site.register(
    Highway, 
    HighwayAdmin, 
)

geom.views.py (this doesn't)

def geojson_highway_all(request):

    geojsonformat = serialize('geojson', 
          Highway.objects.all(),
          geometry_field='mline',
          fields = (
            'pk',
            'cameras_per_km'  # <-- I want this to show
          )
    )

    return HttpResponse(geojsonformat)

geom.urls.py

from django.urls import path
from . import views

app_name = 'geom'

urlpatterns = [
    path('highways.geojson', views.geojson_highway_all, name='highways.geojson'),
]
like image 734
Anton vBR Avatar asked Dec 17 '25 17:12

Anton vBR


1 Answers

Update: I (Anton vBR) have now rewritten this answer completely but think @ruddra deserves some credit. I am however open for alternative solutions. Hopefullly this answer can helps someone out in the future.


Create a new Serializer based on geojson serializer

geom.views.py

from django.contrib.gis.serializers.geojson import Serializer 

class CustomSerializer(Serializer):

    def end_object(self, obj):
        for field in self.selected_fields:
            if field == self.geometry_field or field == 'pk':
                continue
            elif field in self._current.keys():
                continue
            else:
                try:
                    self._current[field] = getattr(obj, field)()
                except AttributeError:
                    pass
        super(CustomSerializer, self).end_object(obj)

geojsonformat = CustomSerializer().serialize(
      Highway.objects.all(),
      geometry_field='mline',
      fields = (
        'pk',
        'cameras_per_km'
      )
like image 175
ruddra Avatar answered Dec 20 '25 07:12

ruddra



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!