Problem:
a = A.objects.get(...)
form = AModelForm(data={...}, instance=a)
if form.is_valid():
a = form.save()
else:
a.calculate_foo_field()
a.last_attempt = datetime.now()
a.save() # Oops, now the instance has the bad data provided to the form
Workarounds:
# Get a fresh copy of ``a``
a = A.objects.get(pk=
a.pk)
# Wasted query
# Also, this won't work in the context of a ``select_for_update`` on the original instance
# Use ``update`` instead
A.objects.filter(pk=
a.pk).update(last_attempt=datetime.now(), ...)
# What about ``calculate_foo_field``?
# Also has the ``select_for_update`` problem
Solution:
a.reset_state() # Resets the instance's field state to the point of creation (using data stored in a ``_state_reset_cache`` dict)
a.reset_foo() # etc.
a.latest_attempt = datetime.now()
a.save()
Problem: Uses more memory per instance
Solution: Add ``QuerySet.cache_for_reset()`` allowing opt-in usage of the feature, treating ``reset_state`` as noop when instance doesn't have the state reset cache.