This is hacky, but you could override _do_update
in your model and simply return True
. Django itself does something kind of hacky on line 893 of _do_update
to suppress the same exception when update_fields
contains column names that do not appear in the model.
The return value from _do_update
triggers the exception you are seeing from this block
I tested the override below and it seemed to work. I feel somewhat dirty for overriding a private-ish method, but I think I will get over it.
def _do_update(self, base_qs, using, pk_val, values, update_fields, forced_update):
updated = super(Article, self)._do_update(base_qs, using, pk_val, values, update_fields, forced_update)
if not updated and Article.objects.filter(id=pk_val).count() == 0:
return True
return updated
This solution could be genericized and moved to a mixin base class if you need to handle this for more than one model.
I used this django management command to test
from django.core.management.base import BaseCommand
from foo.models import Article
class Command(BaseCommand):
def handle(self, *args, **kwargs):
Article.objects.update_or_create(id=1, defaults=dict(label='zulu'))
print('Testing _do_update hack')
article1 = Article.objects.get(id=1)
article1.label = 'yankee'
article2 = Article.objects.get(id=1)
article2.delete()
article1.save(update_fields=['label'])
print('Done. No exception raised')