0

I'm building an application on Django 1.5 that stores location data with PostGIS. For the prototype, the form to create a new location record requires that the user enter the latitude and longitude coordinates (I assumed this would be the easiest setup to code).

I've created a ModelForm like so:

class LocationForm(forms.ModelForm):
  # Custom fields to accept lat/long coords from user.
  latitude  = forms.FloatField(min_value=-90, max_value=90)
  longitude = forms.FloatField(min_value=-180, max_value=180)

  class Meta:
    model   = Location
    fields  = ("name", "latitude", "longitude", "comments",)

So far, so good. However, the Location model doesn't have latitude nor longitude fields. Instead, it uses a PointField to store the location's coordinates:

from django.contrib.gis.db import models

class Location(models.Model):
  name = models.CharField(max_length=200)
  comments = models.TextField(null=True)

  # Store location coordinates
  coords = models.PointField(srid=4326)

  objects = models.GeoManager()

What I'm looking for is where to inject the code that will take values for the latitude and longitude inputs and store them as a Point object in the Location's coords field once the user submits the form with valid values.

E.g., I'm looking for the Django equivalent of Symfony 1.4's sfFormDoctrine::doUpdateObject() method.

3 Answers3

2

With some guidance from stummjr's answer and poking around in django.forms.BaseModelForm, I believe I have found the solution:

class LocationForm(forms.ModelForm):
  ...

  def save(self, commit=True):
    self.instance.coords = Point(self.cleaned_data["longitude"], self.cleaned_data["latitude"])
    return super(LocationForm, self).save(commit)
Community
  • 1
  • 1
0

You could override the save() method in Location model.

class Location(models.Model):
    name = models.CharField(max_length=200)
    comments = models.TextField(null=True)

    # Store location coordinates
    coords = models.PointField(srid=4326)

    objects = models.GeoManager()

    def save(self, *args, **kwargs):
        self.coords =  ... # extract the coords here passed in through kwargs['latitude'] and kwargs['longitude']
        # don't forget to call the save method from superclass (models.Model)
        super(Location, self).save(*args, **kwargs)

Supposing you have this view to process the form:

  def some_view(request):
      lat = request.POST.get('latitude')
      longit = request.POST.get('longitude')
      ...
      model.save(latitude=lat, longitude=longit)

Another option would be to override the save method in your ModelForm.

Community
  • 1
  • 1
Valdir Stumm Junior
  • 4,568
  • 1
  • 23
  • 31
0

Overide Form clean method to set coords

    def clean(self):
        lat = self.data.get("Longitude")
        long = self.data.get("Latitude")
        p = Point(long,lat,srid=4326)
        self.cleaned_data["coords"] = p
        super(LocationForm, self).clean()
Amulya Acharya
  • 701
  • 14
  • 17