Hi
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:
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:
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:
Best,
Rune Kaagaard