update_or_create(defaults=None) sends update_fields=set() rather than None

Thanks for having a look!

It is meant to be persisted. I noticed today I wasn’t handling the case where it shouldn’t be persisted correctly (the empty iterable case).

Here’s a fiddle with what I mean.

If there are no fields to update no save should take place so it could even be argued that save should not be called at all when update_fields is empty

I guess that’s my question – create() delegates to save() without requiring knowledge of whatever fields save() manages itself. But update_or_create() does require this knowledge post ticket-32095.

I’m pretty confident we can’t change update_or_create to pass update_fields or None without defeating the purpose

Ah, right, of course. I guess my choices are:

  • bite bullet: decouple cleaning from save
  • bite bullet: factor recalculations out of save methods into custom fields with pre_save() implemented
  • hack: audit all update_or_create() usage to impart knowledge of the fields that save() manages itself (not future-proof)
  • hack: continue mishandling empty iterables for update_fields in general, but define a custom empty iterable I can sniff for when it’s important to handle it correctly (i.e. when I truly want no fields to be updated)

1 is a huge lift. 2 would grow the number of custom fields more than I’d like. 3 doesn’t sound right. I’ll probably opt for 4, although it’s not strictly correct. I was just checking my understanding before going down that path.