amy
amy copied to clipboard
Double clicking submit button creates duplicate records
In views that create a new record (i.e. not those that update an existing one), double clicking on the submit button can reliably create a duplicate record - i.e. the POST request is created and handled twice.
I keep running into this because of my particular (unusual) mousing patterns and impatience with slightly slow page loads. I've replicated this locally and in test-amy, but haven't tried production. It's slightly annoying, but generally harmless.
I assume that there are some common strategies to avoid this for websites in general, and that we can look into applying one of those here.
From @elichad - Unsure about what it would take to fix it. Has seen it handled on other sites; need to research how this happens. Possibly disable button after clicking once to prevent it from being clicked again.
The key concept here is known as idempotence/idempotency.
I'm roughly following this article to implement this for our Create*
views: Idempotence and POST Requests in Django. This should be a bit more robust than disabling buttons on submit.
Progress on branch feature/2511-Double-clicking-submit-button-creates-duplicate-records
Extra info on an implementation in a major API: https://stripe.com/docs/api/idempotent_requests
Current status:
- [x] implement a mixin to make create views idempotent
- [x] implement middleware to catch duplicate requests
- [ ] figure out what response to return that results in the user seeing the same as they usually would
- [x] create template tag to add idempotence tokens to POST forms, like CSRF tokens
- [ ] ensure all views work as before
- [ ] write plenty of tests
There is a lazier option here, which is to insert a bit of JS everywhere to disable submit buttons on submit. But the solution described above would work for both web and API requests, whereas JS works for web only. Disabling buttons is also not great for accessibility (though in this context, it's not too bad).