2

I've come across two methods of doing this. The accepted answer here suggests:

def save(self, *args, **kwargs):
    instance = super(ModelClass, self).save(commit=False)
    instance.my_stuff = manual_value
    instance.save()

But the following, found here, seems more elegant:

def save(self, *args, **kwargs):
    self.my_stuff = manual_value
    super(ModelClass, self).save(*args, **kwargs)

Is there any reason to choose one over the other, other than the latter being one less line, such as a reason for running the parent save() first?

Community
  • 1
  • 1
StringsOnFire
  • 2,726
  • 5
  • 28
  • 50

2 Answers2

5

The two examples are doing different things. The first is saving the model form's save method, the second is overriding the model's save method.

It only makes sense to override the model's method if you want the value to be set every time the model is saved. If updating the field is related to the form, then overriding the form's save method is the correct thing to do.

In the model form's save method, you have to call save(commit=False) first to get the instance. I wouldn't worry about it being inelegant, it's a very common pattern in Django, and is documented here.

Alasdair
  • 298,606
  • 55
  • 578
  • 516
2

First one will create instance of model, without saving it, then you can add some value (that is required or not) and manually trigger save on that instance.

Second one will save some field on ModelForm (not on actual instance of your model) and then create + save instance of your model.

If in second one you're just setting value on form field that corresponds to model field edited in first example, that will almost work in same way.

Why almost? On second example you have to have that form field inside your form class, on first example you don't. If that field is required, and have been left empty, second example won't validate.

That being said, first example can add or change fields in your model that haven't appeared on form, second example can only modify fields that have been specified inside form class.

GwynBleidD
  • 20,081
  • 5
  • 46
  • 77