Fix auto_now field not updated with save(update_fields=[...])#2122
Fix auto_now field not updated with save(update_fields=[...])#2122Br1an67 wants to merge 3 commits intotortoise:developfrom
Conversation
When calling model.save(update_fields=['field']), fields with auto_now=True were not included in the update, so their timestamps were not refreshed. Now auto_now fields are automatically appended to update_fields before executing the update.
| update_fields = list(update_fields) | ||
| for field_name, field_obj in self._meta.fields_map.items(): | ||
| if field_name not in update_fields and getattr(field_obj, "auto_now", False): | ||
| update_fields.append(field_name) |
There was a problem hiding this comment.
what about queryset .update() and .bulk_update() methods?
Add auto_now fields to BulkUpdateQuery so bulk_update() automatically includes auto_now fields, consistent with Django's behavior. QuerySet.update() intentionally does not handle auto_now — it is a raw SQL operation where the caller provides explicit values, matching Django's documented behavior.
Br1an67
left a comment
There was a problem hiding this comment.
Good catch! I've added support to bulk_update() as well — the new commit auto-includes auto_now fields in BulkUpdateQuery, with a corresponding test.
For QuerySet.update(), this intentionally does not auto-set auto_now — it's a raw SQL operation where the caller provides explicit values. This matches Django's documented behavior.
Yes, that makes sense. The PR looks good to me. This will now solve the ‘auto_now’ fields issue without explicitly passing them in ‘updated_fields’ |
Add auto_now field injection to UpdateQuery so that QuerySet.update() automatically sets auto_now fields to the current time when they are not explicitly specified. Add test_queryset_update_auto_now to verify the behavior.
|
Thanks for the review! Good point about I've updated the PR to handle all three cases:
Added |
|
I am not sure right now if we should include this fix in that way, at least regarding querset.update On one hand that seems logical, but at the same time it is implicit and differs from django behaviour. |
Description
When calling
model.save(update_fields=['some_field']), fields withauto_now=Truewere not automatically included in the update, so their timestamps were not refreshed.Motivation and Context
Fixes #1512
Django's ORM automatically includes
auto_nowfields whenupdate_fieldsis specified. Tortoise-ORM should behave the same way —auto_nowfields should always be updated on save regardless of whether they are explicitly listed inupdate_fields.How Has This Been Tested?
Added
test_update_auto_now_with_update_fieldsintests/test_update.pythat:modifiedtimestamp to the pastnamefield viasave(update_fields=['name'])modified(auto_now) field was also updated to todayChecklist: