Thursday, 6 June 2019

Specify fields of related model in Django GeoJSON serializer field

I am trying to plot the latlong points in the map using geojson serializer. For this functionality, I have two models named Activity and ClusterA.

Activity is a model that stores data for some activity defined in a project. This activity contains a PointField field called location. This is my Activity model:

class Activity(models.Model):
    name = models.CharField(max_length=200)
    description = models.CharField(max_length=500)
    target_number = models.IntegerField(null=True, blank=True)
    target_unit = models.CharField(max_length=200, null=True, blank=True)
    beneficiary_level = models.BooleanField(default=True)
    weight = models.FloatField(default=0)
    location = PointField(geography=True, srid=4326, blank=True, null=True)

    def __str__(self):
        return self.name

    @property
    def latitude(self):
        if self.location:
            return self.location.y

    @property
    def longitude(self):
        if self.location:
            return self.location.x

Similarly, an activity can belong to a cluster. This data is stored in the model ClusterA(Cluster Activity). ClusterA refers to the activities that are specific for a cluster.

Cluster model

class Cluster(models.Model):
    name = models.CharField(max_length=200)
    ward = models.CharField(max_length=200)

    def __str__(self):
        return self.name

ClusterA model

class ClusterA(models.Model):
    activity = models.ForeignKey('Activity', related_name='clustera')
    target_number = models.IntegerField(null=True, blank=True, default=0)
    target_unit = models.CharField(max_length=200, null=True, blank=True, default='')
    time_interval = models.ForeignKey(ProjectTimeInterval, related_name='cainterval', null=True, blank=True)
    target_completed = models.IntegerField(null=True, blank=True, default=0)
    interval_updated = models.BooleanField(default=False)
    target_updated = models.BooleanField(default=False)
    location = PointField(geography=True, srid=4326, blank=True, null=True)

    def __str__(self):
        return self.name

    @property
    def latitude(self):
        if self.location:
            return self.location.y

    @property
    def longitude(self):
        if self.location:
            return self.location.x

    def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
        if not self.id:
            if not self.activity.beneficiary_level:
                self.target_unit = self.activity.target_unit
            self.time_interval = self.activity.time_interval
        return super(ClusterA, self).save()

Now I am using a function that returns the geojson data for the cluster activities as:

def get_map_data(request):
    ca = ClusterA.objects.all()
    data = serialize(
        'geojson',
        ca,
        geometry_field='location',
        fields = ('activity', 'location', )
    )
    print(data)
    return HttpResponse(data)

The output I get is:

{"type": "FeatureCollection", "crs": {"type": "name", "properties": {"name": "EPSG:4326"}}, "features": [{"geometry": {"type": "Point", "coordinates": [85.336775, 27.542718]}, "type": "Feature", "properties": {"activity": 27}}, {"geometry": null, "type": "Feature", "properties": {"activity": 19}}, {"geometry": {"type": "Point", "coordinates": [85.336776, 27.735227]}, "type": "Feature", "properties": {"activity": 26}}]}

The activity field gives the id for the activity. But I require the activity name so that I can display the activity name in the pop up of marker plotted in the map.

This is how I am trying to display the name of activity in popup of the marker:

onEachFeature: function (feature, layer) {
   layer.bindPopup(feature.properties.name);
} 

The popup displays other data if I pass the fields of local model to it.

I have tried using:

fields = ('activity__name', 'location', )

In the get_map_data function, but it does not display the field in the print output as:

{"type": "FeatureCollection", "crs": {"type": "name", "properties": {"name": "EPSG:4326"}}, "features": [{"geometry": {"type": "Point", "coordinates": [85.336775, 27.542718]}, "type": "Feature", "properties": {}}, {"geometry": null, "type": "Feature", "properties": {}}, {"geometry": {"type": "Point", "coordinates": [85.336776, 27.735227]}, "type": "Feature", "properties": {}}]}

As you can see, there is no field specified in the properties of above output.

The help I need is to be able to fetch the name field of the activity model rather than the id.

I am using Django 1.8.



from Specify fields of related model in Django GeoJSON serializer field

No comments:

Post a Comment