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.

Reply via email to