Using pre_save when specifying update_fields
I have a pre_save defined in MyModel that looks something like this:
@receiver(pre_save, sender=MyModel)
def _mymodel_pre_save(sender, instance, **kwargs):
if some_condition():
instance.somecolumn = 'eggs'
i.e. it expects to be able to modify some of the attributes of the MyModel instance and, of course, expects these changes to be saved during the call to save (). I believe this is a fairly typical use of the pre_save function. This works great as long as the save () call specifies update_fields.
I'm wondering if there is a safe and sane way to use update_fields in the save () call of the MyModel instance at this point. If I naively call:
myinstance = MyModel.objects.get(id=100)
myinstance.othercolumn = 'spam'
myinstance.save(update_fields=['othercolumn'])
The generated UPDATE statement will look like this:
UPDATE "myapp_mymodel" SET "othercolumn" = 'spam' WHERE "myapp_mymodel"."id" = 100
there is no alleged update "somecolumn" from pre_save. I guess this condition can be detected from within pre_save by looking at the update_fields that are made available to the pre_save function (like frozenset), but I don't see any way for pre_save to force the intended changes when the caller has a more restrictive set of update_fields. as in the above example. Or is there a workaround?
source to share
Bypass:
@receiver(pre_save, sender=MyModel)
def _mymodel_pre_save(sender, instance, **kwargs):
if some_condition():
instance.somecolumn = 'eggs'
instance.save()
Notice the additional call to "instance.save ()".
But you have to make sure that some_condition () is no longer True after instance.somecolumn = 'eggs' has been executed. If not, it will go into a call store / prestore / store / prestore cycle
source to share