dreadlock aka django-admin-read
What is this about ?
dreadlock aims to enable the Django admin with implicit read permission, meaning there is not another permission added to the framework. So the permission system is not modified, and you can just use it the same way.
Requirements
Django 1.2 or newer is required. dreadlock uses the readonly_fields feature to achieve it's goal.
Install
Install using pip:
pip install -e hg+
or clone the hg archive and use setup.py:
python setup.py install
Usage
Then, add dreadlock to INSTALLED_APPS in your settings file:
INSTALLED_APPS = ( 'dreadlock', ... )
Template loading
The application order matter. dreadlock must de declared before django.contrib.admin. This way, and due to the template loading system, dreadlock's template will be load first and instead of Django admin ones. dreadlock implements its own templates and overload some from Django admin. Also, check that 'django.template.loaders.app_directories.Loader' is in your TEMPLATE_LOADER settings (default), otherwise templates will not be loaded from the application.
If you don't want to put dreadlock on top of the INSTALLED_APPS, an alternate method is to add the dreadlock template path to the TEMPLATE_DIRS settings. This way, dreadlock templates will also be correctly loaded.
See the Django template documentation for more information.
dreadlock is now up and running. Now, you need to declare your admin options to turn models into readable ones.
Model registration
To enable a model with read admin, use the dreadlock ModelAdminRead instead of the ModelAdmin that comes with Django admin. Following the example given into ModelAdmin documentation:
from django.contrib import admin from myproject.myapp.models import Author from dreadlock.admin import ModelAdminRead class AuthorAdmin(ModelAdminRead): pass admin.site.register(Author, AuthorAdmin)
At this time of writing you only have enabled read access to Author model meaning that only views handle by the ModelAdminRead are read-based. But the admin site is still powered by change permission. So, only user that have change permisison tied to this model can list them on the Django admin index page. We're going to fix that.
How to enable Django admin site to be readable ?
To set up a Django admin site to be readable, you need to use the AdminSiteRead that comes with dreadlock. To achieve that, the easiest solution is to change the default admin site instance that comes with Django with an AdminSiteRead instance. Edit your urls.py like so:
from django.conf.urls.defaults import * # Uncomment the next two lines to enable the admin: from django.contrib import admin from dreadlock.sites import AdminSiteRead admin.site = AdminSiteRead())), )
Save your admin.py file and launch python manage.py runserver to test it. You should now see on the admin index page the change link named view. Congratulations, it's working. Test it and experiment the new workflow of your model.
Best practice
I recommend you to have a dedicated admin site to handle only the readable objects, and another regular admin site to your trusted users. This way, you don't have to monkey-patch urls.py and also, you have the control over the models you want to expose to your user.
How to enable all admin registered objects ?
Astute readers should mention that only models registered with AdminModelRead act like expected. Others models use the old wrokflow. Why ? Simply, because there are registered to the admin site using ModelAdmin, and there is no way to edit all the models by hand. So, a solution is to replace ModelAdmin instances to ModelAdminRead ones. To do so, edit your urls.py like so:
from django.conf.urls.defaults import * # Uncomment the next two lines to enable the admin: from django.contrib import admin from dreadlock.sites import AdminSiteRead from dreadlock.admin import ModelAdminRead admin.site = AdminSiteRead() admin.ModelAdmin = ModelAdminRead)), )
Sure, it's not the more elegant way to make things, but it does the job.
Why this app ?
Django admin is a killer feature. And when you show it to your customer, it's a contract seller. But sometimes, a customer will aks you: "Yeah, this admin is great. Can i have it user, but only for read, becaiuse id don't want my user to be able to modify some/all objects ?" Your first reaction is: "Sure, i'll use generic views to handle that.". But, this way, you loose all great things that comes free with the admin like filters, search and the design !
This situation really happened to me, and a client really wanted the admin interface but with read permission. So, i dive into Django documentation and source code and made this app. Now, i release it as an open-source software. Hope it helps.
Has the workflow changed ?
Yes. The Django admin's basic workflow is the following -- considering the user have the change permission on the model:
- select an application or a model
- list the objects that belong to this model, and select one
- edit the selected object
With dreadlock, the workflow is now the following :
- select an application or a model
- list the objects that belong to this model, and select one
- view the selected object
- edit the selected object
As you can see, with dreadlock before editing and object, you view it. This is the only main difference between the workflow coming with Django admin and dreadlock.
Is it an ugly/monkey patch ?
Sorf of. Django admin comes with change permission, and most of the views involved need this permission to work. The point here is to allow admin user to list and view objects in the admin. So, in order to achieve this, dreadlock re-implement some of the views to (re)move the change permission checking when needed.
Does it means that every object is editable without the change permission required ?
No. Changing an object still need change permission. Only viewing object doesn't required any permission, because dreadlock considers that an admin user comes with an implicit read permission.
Moreover, it needs to say that the object is only editable whether the user gets the change permission, like Django admin.
Why this name ?
Well, first i wanted to call this application django-admin-read, but although it's self explanatory, the name was too long and boring. So, i tried to find a shortened name and after some thoughts, i came with "dreadlock" which is funnier, doesn't it ?