1

I have a DRF API which contains a field that's being set in the serializer:

class KnownLocation(models.Model):

    latitude = models.FloatField(name="Latitude",
                                 verbose_name='Latitude',
                                 unique=True, max_length=255, blank=False,
                                 help_text="Enter the location's Latitude, first when extracting from Google Maps.",
                                 )

    longitude = models.FloatField(name="Longitude",
                                  verbose_name="Longitude",
                                  unique=True, max_length=255, blank=False,
                                  help_text="Enter the location's Longitude, second when extracting from Google Maps.",
                                  )

    elevation = models.FloatField(name="elevation",
                                  help_text="Enter the location's ~Sea Level~ elevation, or Leave empty for auto-fill "
                                            "by me :). ",
                                  verbose_name="Elevation in meters",
                                  blank=True,
                                  default=DEFAULT_VALUE
                                  )

And the serializer:

class KnownLocationSerializer(HyperlinkedModelSerializer):
    date_added = DateTimeField(format="%d-%m-%Y", required=False, read_only=True)
    elevation = SerializerMethodField()

    def validate_elevation(self, value):
        """
        Validate that elevation of location has been updated already.
        """
        if value is None or 1:
            raise APIException.elevation.throw()
        return value

    def get_elevation(self, obj):
        """
        This method, which is connected to SerializerMethodField, checks if the object's elevation value exists,
        if not, it fetches it.
        """
        elevation = obj.elevation
        if elevation is None or 1:
            elevation = get_elevation(lat=obj.Latitude, lon=obj.Longitude)
            elevation = round(elevation)
            return elevation
        pass

The method works and fetches the elevation, yet, it doesn't save it to the DB. did I miss that part in the docs? so, how can I save it to the DB, using save didn't work for me:

    def save(self, **kwargs):
        latitude, longitude = self.instance.latitude, self.instance.longitude
        self.instance.elevation = get_elevation(latitude, longitude)
        self.instance.save()
        return self.instance

    def validate_elevation(self, value):
        """
        Validate that elevation of location has been updated already.
        """
        if value is None or 1:
            raise APIException.elevation.throw()
        return value

1 Answer 1

2

Documentation is clear about this - SerializerMethodField is read-only.

What you need, I think, is a custom field. Django Rest Framework How to update SerializerMethodField is a good place to start.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.