Hi I've made a branch that adds optimistic concurrency control to the admin: https://github.com/runekaagaard/django-lock-the-admin/compare/adminlock. It works for the main change object and inlines and has tests. All tests passes with postgres and sqlite.
This prevents users from accidentally overwriting each others changes. To confirm this is is the case today [1]: 1. Open the same change page in the admin in two tabs. 2. Make different modifications to them. 3. Press save in both tabs. 4. The changes in the last saved tab silently overwrites the first ones. In my proposal an edit conflict looks like: <https://lh6.googleusercontent.com/-DS1PceT-_SY/VIWD0fbXVkI/AAAAAAAAG7g/2NkFI-UmoYQ/s1600/Screen%2BShot%2B2014-12-08%2Bat%2B11.55.50%2BAM.png> It works by: - Adding a "admin.Lock" model with version number, pk and content type of the objects being edited. - Adding "lock_version" hidden fields to the main object form and inline forms. - Wrapping the save part of "changeform_view" in a transaction that rolls back if a any object on the page has a stale version. - Showing an error message if the user wasn't allowed to save. What do you think, is this something I should open a ticket for and start working on? *Scope* This proposal doesn't cover editable inlines [2], but they are kind of unusable as is, unless you are a single admin, that really knows what you are doing. I would love to work on that for v1.8, but prefers getting a locking mechanism in place first without it!? The same goes for locking of admin actions and the cryptic error you get when you are deleting an already deleted inline [3]. Rails supports both pessimistic and optimistic locking [4] [5]. It would be cool to have a "contrib.locking" module, but I think it's out of scope for this proposal. Plus, it will be easy to change the locking method when/if such a module happens. *Implementation* 1. Should there be a settings.ADMIN_USE_LOCKING? 2. Should there be a ModelAdmin.use_locking property? 3. Instead of having an "admin.Lock" model you could have a "version" field on each table and make a LockingModel available. I didn't do that because i wanted to prevent data loss in the admin out of the box, also for existing projects. What's your take on that? *Should it be a third party app?* I think the "killer app" for Django should be safe by default. Third party solutions already exists, though [6] [7] [8]. *Test project* To test the UI of this feature, use the adminlock-test branch: git clone https://github.com/runekaagaard/django-lock-the-admin.git cd django-lock-the-admin git checkout adminlock-test cd test_project python manage.py migrate python manage.py createsuperuser python manage.py runserver *References:* - [1] https://code.djangoproject.com/ticket/11652 - [2] https://code.djangoproject.com/ticket/11313 - [3] https://code.djangoproject.com/ticket/15574 - [4] http://edgeapi.rubyonrails.org/classes/ActiveRecord/Locking/Optimistic.html - [5] http://api.rubyonrails.org/classes/ActiveRecord/Locking/Pessimistic.html - [6] https://github.com/saxix/django-concurrency - [7] https://github.com/RobCombs/django-locking - [8] https://github.com/runekaagaard/django-admin-locking Best, Rune Kaagaard -- You received this message because you are subscribed to the Google Groups "Django developers (Contributions to Django itself)" group. To unsubscribe from this group and stop receiving emails from it, send an email to [email protected]. To post to this group, send email to [email protected]. Visit this group at http://groups.google.com/group/django-developers. To view this discussion on the web visit https://groups.google.com/d/msgid/django-developers/ec0a7667-68c3-4ae7-8e46-71cc7c9bbc01%40googlegroups.com. For more options, visit https://groups.google.com/d/optout.
