Closed
Description
EDIT: For the current status of the issue, skip to #4231 (comment)
===
I'm having an issue implementing an Optimistic Concurrency library on an application that uses DRF to interact with the database. I'm trying to:
- Confirm that the behavior I'm seeing is attributable to DRF
- Confirm that this is the intended behavior
- Determine if there's any practical way to overcome this behavior
I recently added optimistic concurrency to my Django application. To save you the Wiki lookup:
- Every model has a version field
- When an editor edits an object, they get the version of the object they're editing
- When the editor saves the object, the included version number is compared to the database
- If the versions match, the editor updated the latest document and the save goes through
- If the versions don't match, we assume a "conflicting" edit was submitted between the time the editor loaded and saved so we reject the edit
- If the version is missing, we cannot do testing and should reject the edit
I had a legacy UI talking through DRF. The legacy UI did not handle version numbers. I expected this to cause concurrency errors, but it did not. If I understand the discussion in #3648 correctly:
- DRF merges the PUT with the existing record. This causes a missing version ID to be filled with the current database ID
- Since this always provides a match, omitting this variable will always break an optimistic concurrency system that communicates across DRF
There are no easy options (like making the field "required") to ensure the data is submitted every time.(edit: you can workaround the issue by making it required as demonstrated in this comment)
Steps to reproduce
- Setup an Optimistic Concurrency field on a model
- Create a new instance and update several times (to ensure you no longer have a default version number)
- Submit an update (PUT) through DRF excluding the version ID
Expected behavior
The missing version ID should not match the database and cause a concurrency issue.
Actual behavior
The missing version ID is filled by DRF with the current ID so the concurrency check passes.