13

I am overriding the save method on one of my models:

def save(self, *args, **kwargs):
    self.set_coords()
    super(Post, self).save(*args, **kwargs)

def __unicode__(self):
    return self.address

# set coordinates
def set_coords(self):
    toFind = self.address + ', ' + self.city + ', ' + \
        self.province + ', ' + self.postal

    (place, location) = g.geocode(toFind)

    self.lat = location[0]
    self.lng = location[1]

However, I only want to run set_coords() once, when the post is being created. This function should not run when the model is being updated.

How can I accomplish this? Is there any way of detecting if the model is being created or updated?

AlexBrand
  • 11,971
  • 20
  • 87
  • 132

2 Answers2

33
def save(self, *args, **kwargs):
    if not self.pk:
        self.set_coords()
    super(Post, self).save(*args, **kwargs)
artu-hnrq
  • 1,343
  • 1
  • 8
  • 30
jagm
  • 576
  • 4
  • 6
  • Can you please tell me that. Return should be used or not on line `super(Post, self).save(*args, **kwargs)`. It works without return. – Vaibhav Jain Oct 12 '14 at 13:15
3

I think the correct way to do it is using post_save signal:

def set_coords(sender, **kw):
    model_instance = kw["instance"]
    if kw["created"]:
        toFind = model_instance.address + ', ' + model_instance.city + ', ' + \
        model_instance.province + ', ' + model_instance.postal
        (place, location) = g.geocode(toFind)
        model_instance.lat = location[0]
        model_instance.lng = location[1]
        model_instance.save()
post_save.connect(set_coords, sender=MyModel)
  • 1
    I would say that signals are a better call to change behaviour of models we don't have access to. Despite of being useful either way. ;) – Jayme Tosi Neto Jan 11 '17 at 23:01