{"action":"created","issue":{"url":"https://api.github.com/repos/tomchristie/django-rest-framework/issues/4231","repository_url":"https://api.github.com/repos/tomchristie/django-rest-framework","labels_url":"https://api.github.com/repos/tomchristie/django-rest-framework/issues/4231/labels{/name}","comments_url":"https://api.github.com/repos/tomchristie/django-rest-framework/issues/4231/comments","events_url":"https://api.github.com/repos/tomchristie/django-rest-framework/issues/4231/events","html_url":"https://github.com/tomchristie/django-rest-framework/issues/4231","id":163071672,"number":4231,"title":"Optimistic Concurrency and PUT Logic","user":{"login":"claytondaley","id":1097439,"avatar_url":"https://avatars.githubusercontent.com/u/1097439?v=3","gravatar_id":"","url":"https://api.github.com/users/claytondaley","html_url":"https://github.com/claytondaley","followers_url":"https://api.github.com/users/claytondaley/followers","following_url":"https://api.github.com/users/claytondaley/following{/other_user}","gists_url":"https://api.github.com/users/claytondaley/gists{/gist_id}","starred_url":"https://api.github.com/users/claytondaley/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/claytondaley/subscriptions","organizations_url":"https://api.github.com/users/claytondaley/orgs","repos_url":"https://api.github.com/users/claytondaley/repos","events_url":"https://api.github.com/users/claytondaley/events{/privacy}","received_events_url":"https://api.github.com/users/claytondaley/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/tomchristie/django-rest-framework/labels/Needs%20further%20review","name":"Needs further review","color":"c7def8"}],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":10,"created_at":"2016-06-30T03:06:23Z","updated_at":"2016-07-30T01:35:07Z","closed_at":"2016-07-04T14:53:47Z","body":"I'm having an issue implementing an [Optimistic Concurrency library](https://github.com/saxix/django-concurrency) on an application that uses DRF to interact with the database.  I'm trying to:\r\n\r\n- Confirm that the behavior I'm seeing is attributable to DRF\r\n- Confirm that this is the intended behavior\r\n- Determine if there's any practical way to overcome this behavior\r\n\r\nI recently added optimistic concurrency to my Django application.  To save you the Wiki lookup:\r\n\r\n - Every model has a version field\r\n - When an editor edits an object, they get the version of the object they're editing\r\n - When the editor saves the object, the included version number is compared to the database\r\n - If the versions match, the editor updated the latest document and the save goes through\r\n - 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\r\n - If the version is missing, we cannot do testing and should reject the edit\r\n\r\nI 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:\r\n\r\n - DRF merges the PUT with the existing record.  This causes a missing version ID to be filled with the current database ID\r\n - Since this **always** provides a match, omitting this variable will always break an optimistic concurrency system that communicates across DRF\r\n - There are no easy options (like making the field \"required\") to ensure the data is submitted every time.\r\n\r\n## Steps to reproduce\r\n\r\n1. Setup an Optimistic Concurrency field on a model\r\n1. Create a new instance and update several times (to ensure you no longer have a default version number)\r\n1. Submit an update (PUT) through DRF excluding the version ID\r\n\r\n## Expected behavior\r\n\r\nThe missing version ID should cause a concurrency issue.\r\n\r\n## Actual behavior\r\n\r\nThe missing version ID is filled by DRF with the current ID so the concurrency does not occur"},"comment":{"url":"https://api.github.com/repos/tomchristie/django-rest-framework/issues/comments/236331296","html_url":"https://github.com/tomchristie/django-rest-framework/issues/4231#issuecomment-236331296","issue_url":"https://api.github.com/repos/tomchristie/django-rest-framework/issues/4231","id":236331296,"user":{"login":"claytondaley","id":1097439,"avatar_url":"https://avatars.githubusercontent.com/u/1097439?v=3","gravatar_id":"","url":"https://api.github.com/users/claytondaley","html_url":"https://github.com/claytondaley","followers_url":"https://api.github.com/users/claytondaley/followers","following_url":"https://api.github.com/users/claytondaley/following{/other_user}","gists_url":"https://api.github.com/users/claytondaley/gists{/gist_id}","starred_url":"https://api.github.com/users/claytondaley/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/claytondaley/subscriptions","organizations_url":"https://api.github.com/users/claytondaley/orgs","repos_url":"https://api.github.com/users/claytondaley/repos","events_url":"https://api.github.com/users/claytondaley/events{/privacy}","received_events_url":"https://api.github.com/users/claytondaley/received_events","type":"User","site_admin":false},"created_at":"2016-07-30T01:35:07Z","updated_at":"2016-07-30T01:35:07Z","body":"Was this left closed on accident? I responded to the specific question and didn't hear a reason what was wrong with the proposal."}}
{"actor":{"display_login":"claytondaley"}}