Throughout this tutorial, we’ll walk you through the creation of a basic project and a issue process using default template.

Sample project

You can find sample code of using django-lb-workflow in testproject/ and lbworkflow/tests/.

Start a new project and config it

Install django-lb-workflow with all option requires:

pip install --upgrade django-lb-workflow[options]

Creating a project:

$ django-admin.py startproject helloword

Add the following code in the file settings.py:









# bower
STATICFILES_FINDERS += (('djangobower.finders.BowerFinder'),)


    # POLYFILLS: javascript fallback solutions for older browsers.
    # CSS3 selectors for IE 6-8.
    # min/max width media queries for IE 6-8.
    # CSS3 styles for IE 6-8.
    # HTML5 tag support for IE 6-8.


# django-compressor
STATICFILES_FINDERS += (('compressor.finders.CompressorFinder'),)
    ('text/coffeescript', 'coffee --compile --stdio'),
    ('text/less', 'lessc {infile} {outfile}'),
    ('text/x-sass', 'sass {infile} {outfile}'),
    ('text/x-scss', 'sass --scss {infile} {outfile}'),


LOGIN_URL = '/admin/login/'
LOGOUT_URL = '/admin/logout/'

MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
MEDIA_URL_ = '/media/'

STATIC_ROOT = os.path.join(BASE_DIR, 'collectedstatic')


Edit the file urls.py:

from django.conf.urls import include
from django.conf.urls import url
from django.contrib import admin
from django.views.generic import RedirectView

urlpatterns = [
    url(r'^$', RedirectView.as_view(url='/wf/list/'), name='home'),
    url(r'^admin/', admin.site.urls),
    url(r'^wf/', include('lbworkflow.urls')),
    url(r'^attachment/', include('lbattachment.urls')),

Create base templates for project.


{% extends "lbadminlte/base.html" %}

{% load staticfiles %}

{% block head_ext %}
  <link href="{% static '/css/lbworkflow.css' %}" rel="stylesheet" type="text/css" />
{% endblock %}

{% block footer_ext %}
  <script src="{% static 'js/lbworkflow.js' %}" type="text/javascript"></script>
  <script type="text/javascript">
    URL_UPLOAD_ATTACH = "{% url 'lbattachment_upload__' %}";
{% endblock %}


{% extends "lbadminlte/base_ext.html" %}

{% block left_side %}
  <section class="sidebar">
    <ul class="sidebar-menu">
      <li id="id-nav-todo">
        <a href="{% url 'wf_todo' %}">
          <i class="fa fa-th"></i> Todo
          <small class="badge pull-right bg-red todo-count hide"></small>
      <li id="id-nav-mywf">
        <a href="{% url 'wf_my_wf' %}">
          <i class="fa fa-th"></i> My
      <li id="id-nav-start-wf">
        <a href="{% url 'wf_start_wf' %}">
          <i class="fa fa-th"></i> Submit
      <li id="id-nav-list-wf">
        <a href="{% url 'wf_list_wf' %}">
          <i class="fa fa-th"></i> All
      <li id="id-nav-report-list">
        <a href="{% url 'wf_report_list' %}">
          <i class="fa fa-th"></i> Report list
{% endblock %}


{% extends "lbadminlte/base_form.html" %}

Install required static package:

$ cd helloword
$ python manager bower install

run the following command to create database and create two superuser admin and vicalloy:

$ python manage.py migrate
$ python manage.py createsuperuser
$ python manage.py createsuperuser

Start the development server:

$ python manage.py runserver

Now, open a Web browser and go to “/” on your local domain – e.g., . You should see the admin’s login screen. After login you can see the home page of this project.

Start a new flow

Create app and generate base code

Creating the issue app:

$ python manage.py startapp issue

Add issue to INSTALLED_APPS in settings.py:


Creating models:

from django.db import models

from lbworkflow.models import BaseWFObj

class Issue(BaseWFObj):
    title = models.CharField('Title', max_length=255)
    summary = models.CharField('Summary', max_length=255)
    content = models.TextField('Content', blank=True)

    def __str__(self):
        return self.title

python manager.py shell to open django shell, and run the following code to generate skeleton code:

>>> from lbworkflow.flowgen import FlowAppGenerator
>>> from issue.models import Issue as wf_class
>>> FlowAppGenerator().gen(wf_class)

run the following command to update database:

$ python manage.py makemigrations issue
$ python manage.py migrate

Config flow

You can config flow in django admin or create a python file and execute it. Config the flow by code issue/wfdata.py:

from lbworkflow.core.datahelper import create_node
from lbworkflow.core.datahelper import create_category
from lbworkflow.core.datahelper import create_process
from lbworkflow.core.datahelper import create_transition

def load_data():

def load_issue():
    """ load_[wf_code] """
    category = create_category('5f31d065-00cc-0020-beea-641f0a670010', 'HR')
    process = create_process('issue', 'Issue', category=category)
    create_node('5f31d065-00a0-0020-beea-641f0a670010', process, 'Draft', status='draft')
    create_node('5f31d065-00a0-0020-beea-641f0a670020', process, 'Given up', status='given up')
    create_node('5f31d065-00a0-0020-beea-641f0a670030', process, 'Rejected', status='rejected')
    create_node('5f31d065-00a0-0020-beea-641f0a670040', process, 'Completed', status='completed')
    create_node('5f31d065-00a0-0020-beea-641f0a670050', process, 'A1', operators='[vicalloy]')
    create_transition('5f31d065-00e0-0020-beea-641f0a670010', process, 'Draft,', 'A1')
    create_transition('5f31d065-00e0-0020-beea-641f0a670020', process, 'A1,', 'Completed')

Add the following code in the file settings.py:

    'issue': 'issue',

run the following command to load flow config to database:

$ python manage.py callfunc lbworkflow.wfdata.load_data
$ python manage.py callfunc issue.wfdata.load_data

Submit and audit

Now we can start the server and submit a issue. We also can audit the issue.

Start the development server:

$ python manage.py runserver
  • Left menu
    • Todo All task need you todo
    • My All process you submitted
    • Submit Submit a new process
    • All You process that you can see
    • Report list Report list