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?

+3


source to share


1 answer


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

+1


source







All Articles