Fix bug where ModificationTimestampField would not automatically update its value.
Review Request #13261 — Created Sept. 6, 2023 and submitted
As discussed in /r/13260, it was discovered that the
ModificationTimestampField
had a bug where sometimes the field wouldn't
automatically update to a new value when it was supposed to. Review Board uses
this field for its "last updated" timestamp on review request and drafts, and
this timestamp sometimes wasn't being updated when we would save changes on a
review request or draft. Specifically, this would happen whenever we tried to
save changes on objects that were fetched through a model manager (i.e. objects
fromModel.objects
).
ModificationTimeStampField
takes care to not overwrite manually set values by
tracking modification state in its__set__
method. If__set__
was called,
then we assume that the field value was manually set and we give the field a
modified
state. But when an object is fetched through a manager, the
__set__
method for the field gets called when creating the object instance.
This makes theModificationTimestampField
think that the value has been
manually set, even though it hasn't been. Previously we were using a
first_set
state to handle the case when__set__
is called during object
initialization, but this wasn't hooked up correctly and didn't actually work.
This change addresses the case by checking if the field value actually exists
in the object's attributes dictionary, and if not then we know that the field
is being set for the first time during object creation and its not being
manually set. We also add unit tests for this case.
- Ran unit tests.
- Ran unit tests (including my newly added ones) without the fix to
ModificationTimestampField
, saw that the cases where we fetch objects
through a model manager and save those would not properly update the
timestamp. - Used in a Review Board change.
Summary | ID |
---|---|
b4c0892169016f91d9feec869ea910047b8eba52 |
- Description:
-
As discussed in /r/13260, it was discovered that the
ModificationTimestampField
had a bug where sometimes the field wouldn't~ automatically update to a new value when it was supposed to. This would happen ~ because for some reason, the __set__
method for a field on a model gets~ called when fetching model instance through their model manager. This makes ~ ModificationTimestampField
think that the value is being manually set, so it~ won't overwrite it. This change fixes that and adds unit tests for this case. ~ automatically update to a new value when it was supposed to. Review Board uses ~ this field for its "last updated" timestamp on review request and drafts, and ~ this timestamp sometimes wasn't being updated when we would save changes on a ~ review request or draft. Specifically, this would happen whenever we tried to ~ save changes on objects that were fetched through a model manager (i.e. objects + from Model.objects
).+ + ModificationTimeStampField
takes care to not overwrite manually set values.+ But when an object is fetched through a manager, the fields of the object + get manually set when creating the object instance. So this makes the + ModificationTimestampField
think that its value is being manually set, so it+ won't overwrite values on objects fetched through a manager, even when they + are not actually being manually set. This change fixes + that and adds unit tests for this case. - Testing Done:
-
- Ran unit tests.
~ - Ran unit tests (including my newly added ones) without the fix to
ModificationTimestampField
, saw that the cases of fetching from a
model manager would fail.
~ - Ran unit tests (including my newly added ones) without the fix to
ModificationTimestampField
, saw that the cases where we fetch objects
through a model manager and save those would not properly update the
timestamp.
- Used in a Review Board change.
- Commits:
-
Summary ID bd0b16872af1097f16e26be0cb2e2230129f675b 4f08f86676da268fb2bd35e56be9931cf3b1fc14
Checks run (2 succeeded)
- Change Summary:
-
- Got rid of the
first_set
state since we don't actually use it or need it anymore. - Hopefully clarified things in the description.
- Updated some docs for better clarification too.
- Got rid of the
- Description:
-
As discussed in /r/13260, it was discovered that the
ModificationTimestampField
had a bug where sometimes the field wouldn'tautomatically update to a new value when it was supposed to. Review Board uses this field for its "last updated" timestamp on review request and drafts, and this timestamp sometimes wasn't being updated when we would save changes on a review request or draft. Specifically, this would happen whenever we tried to save changes on objects that were fetched through a model manager (i.e. objects from Model.objects
).~ ModificationTimeStampField
takes care to not overwrite manually set values.~ But when an object is fetched through a manager, the fields of the object ~ get manually set when creating the object instance. So this makes the ~ ModificationTimestampField
think that its value is being manually set, so it~ won't overwrite values on objects fetched through a manager, even when they ~ are not actually being manually set. This change fixes ~ that and adds unit tests for this case. ~ ModificationTimeStampField
takes care to not overwrite manually set values by~ tracking modification state in its __set__
method. If__set__
was called,~ then we assume that the field value was manually set and we give the field a ~ modified
state. But when an object is fetched through a manager, the~ __set__
method for the field gets called when creating the object instance.~ This makes the ModificationTimestampField
think that the value has been~ manually set, even though it hasn't been. Previously we were using a + first_set
state to handle the case when__set__
is called during object+ initialization, but this wasn't hooked up correctly and didn't actually work. + This change addresses the case by checking if the field value actually exists + in the object's attributes dictionary, and if not then we know that the field + is being set for the first time during object creation and its not being + manually set. We also add unit tests for this case. - Commits:
-
Summary ID 4f08f86676da268fb2bd35e56be9931cf3b1fc14 b4c0892169016f91d9feec869ea910047b8eba52