Package: django-werewolf
Packagedjango-werewolfDescriptionItem publishing workflow for Django (fully integrated into Django admin).PrerequisitesDjango 1.5.+Python 2.6.8+, 2.7.+, 3.3.+InstallationInstall django-werewolf into your virtual environment:$ pip install django-werewolfAddwerewolfto yourINSTALLED_APPS.That’s all. See theUsage and examplessection for more.Usage and examplesIt’s all about item publishing in a workflow. We have variousintermediatestatuses (work in-progress) and a
finalstatuswhich means that the item is actually published. Some users should be able to set the item status
topublished, some others not. This app allows you (and gives you a good working example with pre-configured
Django environment) to write a custom workflow for publishing your items with minimal efforts.For a complete example of a working django-werewolf app see the
(https://github.com/barseghyanartur/django-werewolf/tree/stable/example) and read thereadme.rstof thenewsapp.Imaginary app conceptThere are three user groups. All of them should be able to log into Django admin.WritersEditorsChief EditorsIn short, our imaginary app would work as follows.Chief Editor creates a News item and chooses a Writer and an Editor. The status of a new News item is
then set tonew.Once a News item with statusnewhas been created, both Writer and the Editor assigned do get an e-mail
notification about the fact that a News item has been assigned to them.Writer is supposed to fill the assigned News item with content and once the News item is ready, change
its’ status toready.The assigned Editor would get an e-mail notification about the fact that the News item has been changed toready.The assigned Editor is supposed to check the News item  with statusreadyand if it’s acceptable, change
the News item status toreviewed.Once a News item status has been set toreviewed, the assigned Writer can no longer access it in the Django
admin.The assigned Chief Editor would get an e-mail notification about the fact that the News item has been changed
toreviewed.The assigned Chief Editor is supposed to check the News item with statusreviewedand if it acceptable,
change the News item status topublished.Once a News item status has been set topublished, the assigned Editor can no longer access it in the Django
admin.Once a News item status has been changed topublished, all Chief Editors in the system, as well as the
assigned Writer and Editor get an e-mail notification about the fact that the News item has been published.DemoIn order to be able to quickly evaluate the django-werewolf, a demo app (with a quick installer) has been created
(Debian only). Follow the instructions below for having the demo running within a minute.Grab the latestdjango-werewolf-example-app-install.sh$ wgethttps://raw.github.com/barseghyanartur/django-werewolf/stable/django-werewolf-example-app-install.shCreate a new- or switch to existing- virtual environement, assign execute rights to the installer and run
thedjango-werewolf-example-app-install.sh.$ chmod +x django-werewolf-example-app-install.sh$ ./django-werewolf-example-app-install.shGo to the backend and test the app.URL:http://127.0.0.1:8001/admin/news/newsitem/Admin username: adminAdmin password: testChief Editor username: chief_editorChief Editor password: testEditor username: editorEditor password: testWriter username: writerWriter password: testLet’s now step-by-step review our imaginary example app.settings.py>>> # Workflow statuses; order is preserved.
>>> WEREWOLF_STATUS_CHOICES = (
>>>     ('new', gettext('New')), # New - this is how it's assigned to a writer.
>>>     ('draft', gettext('Draft')), # Draft - this is how the writer works on it.
>>>     ('ready', gettext('Ready')), # Ready to be reviewed by editor.
>>>     ('reviewed', gettext('Reviewed')), # Reviewed by editor (means positive
>>>                                        # and ready to be published).
>>>     ('published', gettext('Published')), # Published.
>>> )
>>>
>>> # Published status.
>>> WEREWOLF_STATUS_PUBLISHED = 'published'
>>>
>>> # When set to True, django-reversion is used.
>>> WEREWOLF_USE_DJANGO_REVERSION = Truenews/models.pyIn the example below we have a basic news item model. We have Chief Editors with full access to news items, we
have editors with less privelleges and Writers with very little privelleges. Chief Editors create articles,
select an Editor and a Writer (both get notified) and let them work on the article. Writers can only set an
article status tonew,draftandready(ready to be checked). Editors review the articles with statusreadyand set the status toreviewed. Chief Editors publish articles that arereviewed. Your
implementation can be as custom as you want it. Think in Django user groups (django.contrib.auth.models.Group)
and Django permissions system.NOTE: See thePermission tuningsection.>>> from django.contrib.auth.models import User
>>>
>>> from werewolf.models import WerewolfBaseModel, WerewolfBaseMeta
>>>
>>> _chief_editors = {'groups__name__iexact': 'Chief editors'}
>>> _editors = {'groups__name__iexact': 'Editors'}
>>> _writers = {'groups__name__iexact': 'Writers'}
>>>
>>> class NewsItem(WerewolfBaseModel): # Important!
>>>     title = models.CharField(_("Title"), max_length=100)
>>>     body = models.TextField(_("Body"))
>>>     date_published = models.DateTimeField(_("Date published"), \
>>>                                           default=datetime.datetime.now())
>>>     author = models.ForeignKey(User, verbose_name=_("Author"), \
>>>                                related_name='authors', \
>>>                                limit_choices_to=_writers)
>>>     editor = models.ForeignKey(User, verbose_name=_("Editor"), \
>>>                                related_name='editors', \
>>>                                limit_choices_to=_editors)
>>>     chief_editor = models.ForeignKey(User, verbose_name=_("Chief editor"), \
>>>                                      related_name='chief_editors', \
>>>                                      limit_choices_to=_chief_editors)
>>>
>>>     class Meta(WerewolfBaseMeta): # Important!
>>>         verbose_name = "News item"
>>>         verbose_name_plural = "News items"Or if you want to define custom permissions for your model as well, do extend the django-werewolf
permissions as follows:>>> from werewolf.models import WerewolfBaseModel
>>> from werewolf.utils import extend_werewolf_permissions
>>>
>>> class NewsItem(WerewolfBaseModel):
>>>     # Your fields here
>>>     class Meta:
>>>         verbose_name = "News item"
>>>         verbose_name_plural = "News items"
>>>
>>>         # Important!
>>>         permissions = extend_werewolf_permissions(
>>>             ('can_change_author', _("Can change author")),
>>>             ('can_change_editor', _("Can change editor")),
>>>             ('can_change_chief_editor', _("Can change chief editor"))
>>>         )news/admin.pyBasic admin for the news item model.NOTE: See thePermission tuningsection.>>> from werewolf.admin import WerewolfBaseAdmin
>>>
>>> from news.models import NewsItem
>>>
>>> class NewsItemAdmin(WerewolfBaseAdmin):
>>>     werewolf_protected_fields = (
>>>         ('author', 'can_change_author'),
>>>         ('editor', 'can_change_editor'),
>>>         ('chief_editor', 'can_change_chief_editor')
>>>     )
>>>
>>> admin.site.register(NewsItem, NewsItemAdmin)Thewerewolf_protected_fieldsproperty is a list of fields that are supposed to be protected. Each item in
the list is a tuple of (field_name_to_protect,required_permission). If given, django-werewolf hides
fields listed as protected from users that do not have the permission required. In order to do so, django-werewolf
overrides the Django’s ModelAdminget_fieldandget_fieldsetsmethods. If you happen to override that
method for your own needs, make sure the it also reflects the django-werewolf concepts.NOTE: If you override thequerysetmethod of your model’s admin class, make sure to see the source code
ofwerewolf.admin.WerewolfBaseAdmin.querysetand copy the approach from there. Otherwise, your users with
no permission to change thepublishedstatus will be able to chgange the status of already published items
to non-published statuses.news/views.py>>> from news.models import NewsItem
>>>
>>> def browse(request):
>>>     news_items = NewsItem._default_manager.published()
>>>     # Other codenews/werewolf_triggers.pyIn order to perform extra tasks on status change, triggers are used. You simply make a new file in your app
calledwerewolf_triggers.pyand define custom classes that should be called when astatusfield of your
model changes to a certain value. Each trigger should subclass thewerewolf.triggers.WerewolfBaseTriggerclass.>>> from werewolf.triggers import WerewolfBaseTrigger, registry
>>>
>>> class StatusNewTrigger(WerewolfBaseTrigger):
>>>     """
>>>     News item status changed to `new`.
>>>     """
>>>     def process(self):
>>>         # Your code
>>>
>>> class StatusReadyTrigger(WerewolfBaseTrigger):
>>>     """
>>>     News item status changed to `ready` (ready for review).
>>>     """
>>>     def process(self):
>>>         # Your code
>>>
>>> # Triggers status change to `new` for news.newsitem model.
>>> registry.register('news', 'newsitem', 'new', StatusNewTrigger)
>>>
>>> # Triggers status change to `ready` for news.newsitem model.
>>> registry.register('news', 'newsitem', 'ready', StatusReadyTrigger)urls.pyIn order to have triggers autodiscovered, place the following code into your mainurlsmodule.>>> from werewolf import autodiscover as werewolf_autodiscover
>>> werewolf_autodiscover()Permission tuningHave in mind ournews.models.NewsItemmodel.Create three user groups:Chief editors (permissions listed):news | News item | Can add News itemnews | News item | Can change authornews | News item | Can change chief editornews | News item | Can change editornews | News item | Can change News itemnews | News item | Can change status to draftnews | News item | Can change status to newnews | News item | Can change status to publishednews | News item | Can change status to readynews | News item | Can change status to reviewednews | News item | Can delete News itemEditors (permissions listed):news | News item | Can change News itemnews | News item | Can change authornews | News item | Can change status to draftnews | News item | Can change status to newnews | News item | Can change status to readynews | News item | Can change status to reviewedWriters (permissions listed):news | News item | Can change News itemnews | News item | Can change status to draftnews | News item | Can change status to newnews | News item | Can change status to readyCreate three users:chief editor: Belongs to groupChief editors.editor: Belongs to groupEditors.writer: Belongs to groupWriters.Now log into the admin with different user and see your admin for theNews item(created items withchiefeditoraccount, then view them witheditorandwriter.That’s it. If somehow you don’t see the new permissions (Can change status to draft,Can change status to new, etc) run a management commandsyncww:$ ./manage.py syncwwRunning the example projectA working example of a django-werewolf app is available here:https://github.com/barseghyanartur/django-werewolf/tree/stable/exampleGo to example/example directory$ cd example/exampleInstall requirements (in your virtual environment)$ pip install -r ../requirements.txtCopy local_settings.example to local_settings.py$ cp local_settings.example local_settings.pyCreate the database$ ./manage.py syncdbInsert example test groups and users$ ./manage.py news_create_groups_and_test_usersRun the project$ ./manage.py runserverLicenseGPL 2.0/LGPL 2.1SupportFor any issues contact me at the e-mail given in theAuthorsection.AuthorArtur Barseghyan <artur.barseghyan@gmail.com>