{"id":13469288,"url":"https://github.com/javrasya/django-river","last_synced_at":"2025-05-15T20:01:08.944Z","repository":{"id":35295581,"uuid":"39556714","full_name":"javrasya/django-river","owner":"javrasya","description":"Django workflow library that supports on the fly changes ⛵","archived":false,"fork":false,"pushed_at":"2023-05-05T21:57:14.000Z","size":685,"stargazers_count":743,"open_issues_count":35,"forks_count":107,"subscribers_count":27,"default_branch":"master","last_synced_at":"2025-05-05T14:28:12.225Z","etag":null,"topics":["django","python","python-2","python-3","state-machine","workflow","workflow-engine"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/javrasya.png","metadata":{"files":{"readme":"README.rst","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null},"funding":{"github":["javrasya"],"patreon":"javrasya","custom":"https://paypal.me/ceahmetdal","open_collective":"django-river"}},"created_at":"2015-07-23T08:56:35.000Z","updated_at":"2025-05-04T21:43:38.000Z","dependencies_parsed_at":"2023-09-29T08:54:37.392Z","dependency_job_id":null,"html_url":"https://github.com/javrasya/django-river","commit_stats":{"total_commits":309,"total_committers":17,"mean_commits":"18.176470588235293","dds":0.08414239482200647,"last_synced_commit":"7e49aa9e555d9f09737e15fb808bf9303cc39e25"},"previous_names":[],"tags_count":36,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/javrasya%2Fdjango-river","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/javrasya%2Fdjango-river/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/javrasya%2Fdjango-river/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/javrasya%2Fdjango-river/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/javrasya","download_url":"https://codeload.github.com/javrasya/django-river/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253002844,"owners_count":21838637,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["django","python","python-2","python-3","state-machine","workflow","workflow-engine"],"created_at":"2024-07-31T15:01:32.061Z","updated_at":"2025-05-15T20:01:08.405Z","avatar_url":"https://github.com/javrasya.png","language":"Python","funding_links":["https://github.com/sponsors/javrasya","https://patreon.com/javrasya","https://paypal.me/ceahmetdal","https://opencollective.com/django-river","https://www.patreon.com/javrasya","https://opencollective.com/django-river/organization/0/website"],"categories":["Python","Library (embedded usage)"],"sub_categories":[],"readme":".. |Build Status| image:: https://travis-ci.org/javrasya/django-river.svg\n    :target: https://travis-ci.org/javrasya/django-river\n\n.. |Coverage Status| image:: https://coveralls.io/repos/javrasya/django-river/badge.svg?branch=master\u0026service=github\n    :target: https://coveralls.io/github/javrasya/django-river?branch=master\n\n.. |Health Status| image:: https://landscape.io/github/javrasya/django-river/master/landscape.svg?style=flat\n    :target: https://landscape.io/github/javrasya/django-river/master\n   :alt: Code Health\n\n.. |Documentation Status| image:: https://readthedocs.org/projects/django-river/badge/?version=latest\n    :target: https://readthedocs.org/projects/django-river/?badge=latest\n\n.. |Quality Status| image:: https://api.codacy.com/project/badge/Grade/c3c73d157fe045e6b966d8d4416b6b17\n   :alt: Codacy Badge\n   :target: https://app.codacy.com/app/javrasya/django-river?utm_source=github.com\u0026utm_medium=referral\u0026utm_content=javrasya/django-river\u0026utm_campaign=Badge_Grade_Dashboard\n\n.. |Downloads| image:: https://img.shields.io/pypi/dm/django-river\n    :alt: PyPI - Downloads\n\n.. |Discord| image:: https://img.shields.io/discord/651433240019599400\n    :target: https://discord.gg/DweUwZX\n    :alt: Discord\n\n.. |Open Collective| image:: https://opencollective.com/django-river/all/badge.svg?label=financial+contributors\n    :alt: Financial Contributors\n    :target: #contributors\n\n.. |Timeline| image:: https://cloud.githubusercontent.com/assets/1279644/9934893/921b543a-5d5c-11e5-9596-a5e067db79ed.png\n\n.. |Logo| image:: docs/logo.svg\n    :width: 200\n\n.. |Create Function Page| image:: docs/_static/create-function.png\n\nDjango River\n============\n\n|Logo|\n\n|Build Status| |Coverage Status| |Documentation Status| |Quality Status| |Downloads| |Discord|\n\nRiver is an open source workflow framework for ``Django`` which supports on\nthe fly changes instead of hard-coding states, transitions and authorization rules.\n\nThe main goal of developing this framework is **to be able to modify literally everything\nabout the workflows on the fly.** This means that all the elements in a workflow like\nstates, transitions or authorizations rules are editable at any time so that no changes\nrequires a re-deploying of your application anymore.\n\n**Playground**: There is a fake jira example repository as a playground of django-river. https://github.com/javrasya/fakejira\n\nDonations\n---------\n\nThis is a fully open source project and it can be better with your donations.\n\nIf you are using ``django-river`` to create a commercial product,\nplease consider becoming our `sponsor`_  , `patron`_ or donate over `PayPal`_\n\n.. _`patron`: https://www.patreon.com/javrasya\n.. _`PayPal`: https://paypal.me/ceahmetdal\n.. _`sponsor`: https://github.com/sponsors/javrasya\n\nDocumentation\n-------------\n\nOnline documentation is available at http://django-river.rtfd.org/\n\nAdvance Admin\n-------------\n\nA very modern admin with some user friendly interfaces that is called `River Admin`_ has been published.\n\n.. _`River Admin`: https://riveradminproject.com/\n\nRequirements\n------------\n* Python (``3.5`` (for Django ``2.2`` only), ``3.6``, ``3.7``, ``3.8``)\n* Django (``2.2``, ``3.0``, ``3.1``)\n* ``Django`` = 2.2 is supported for ``Python`` \u003e= 3.5\n* ``Django`` \u003e= 3.0 is supported for ``Python`` \u003e= 3.6\n\nSupported (Tested) Databases:\n-----------------------------\n\n+------------+--------+---------+\n| PostgreSQL | Tested | Support |\n+------------+--------+---------+\n| 9          |   ✅   |    ✅   |\n+------------+--------+---------+\n| 10         |   ✅   |    ✅   |\n+------------+--------+---------+\n| 11         |   ✅   |    ✅   |\n+------------+--------+---------+\n| 12         |   ✅   |    ✅   |\n+------------+--------+---------+\n\n+------------+--------+---------+\n| MySQL      | Tested | Support |\n+------------+--------+---------+\n| 5.6        |   ✅   |    ❌   |\n+------------+--------+---------+\n| 5.7        |   ✅   |    ❌   |\n+------------+--------+---------+\n| 8.0        |   ✅   |    ✅   |\n+------------+--------+---------+\n\n+------------+--------+---------+\n| MSSQL      | Tested | Support |\n+------------+--------+---------+\n| 19         |   ✅   |    ✅   |\n+------------+--------+---------+\n| 17         |   ✅   |    ✅   |\n+------------+--------+---------+\n\n\nUsage\n-----\n1. Install and enable it\n\n   .. code:: bash\n\n       pip install django-river\n\n\n   .. code:: python\n\n       INSTALLED_APPS=[\n           ...\n           river\n           ...\n       ]\n\n2. Create your first state machine in your model and migrate your db\n\n    .. code:: python\n\n        from django.db import models\n        from river.models.fields.state import StateField\n\n        class MyModel(models.Model):\n            my_state_field = StateField()\n\n3. Create all your ``states`` on the admin page\n4. Create a ``workflow`` with your model ( ``MyModel`` - ``my_state_field`` ) information on the admin page\n5. Create your ``transition metadata`` within the workflow created earlier, source and destination states\n6. Create your ``transition approval metadata`` within the workflow created earlier and authorization rules along with their priority on the admin page\n7. Enjoy your ``django-river`` journey.\n\n    .. code-block:: python\n\n        my_model=MyModel.objects.get(....)\n\n        my_model.river.my_state_field.approve(as_user=transactioner_user)\n        my_model.river.my_state_field.approve(as_user=transactioner_user, next_state=State.objects.get(label='re-opened'))\n\n        # and much more. Check the documentation\n\n.. note::\n    Whenever a model object is saved, it's state field will be initialized with the\n    state is given at step-4 above by ``django-river``.\n\nHooking Up With The Events\n--------------------------\n\n`django-river` provides you to have your custom code run on certain events. And since version v2.1.0 this has also been supported for on the fly changes. You can\ncreate your functions and also the hooks to a certain events by just creating few database items. Let's see what event types that can be hooked a function to;\n\n* An approval is approved\n* A transition goes through\n* The workflow is complete\n\nFor all these event types, you can create a hooking with a given function which is created separately and preliminary than the hookings for all the workflow objects you have\nor you will possible have, or for a specific workflow object. You can also hook up before or after the events happen.\n\n1. Create Function\n^^^^^^^^^^^^^^^^^^\n\nThis will be the description of your functions. So you define them once and you can use them with multiple hooking up. Just go to ``/admin/river/function/`` admin page\nand create your functions there. ``django-river`` function admin support python code highlights.\n\n   .. code:: python\n\n       INSTALLED_APPS=[\n           ...\n           codemirror2\n           river\n           ...\n       ]\n\nHere is an example function;\n\n   .. code:: python\n\n        from datetime import datetime\n\n        def handle(context):\n            print(datetime.now())\n\n**Important:** **YOUR FUNCTION SHOULD BE NAMED AS** ``handle``. Otherwise ``django-river`` won't execute your function.\n\n``django-river`` will pass a ``context`` down to your function in order for you to know why the function is triggered or for which object or so. And the ``context`` will look different for\ndifferent type of events. Please see detailed `context documentation`_ to know more on what you would get from context in your functions.\n\nYou can find an `advance function example`_ on the link.\n\n|Create Function Page|\n\n.. _`context documentation`: https://django-river.readthedocs.io/en/latest/hooking/function.html#context-parameter\n.. _`advance function example`: https://django-river.readthedocs.io/en/latest/hooking/function.html#example-function\n\n2. Hook It Up\n^^^^^^^^^^^^^\n\nThe hookings in ``django-river`` can be created both specifically for a workflow object or for a whole workflow. ``django-river`` comes with some model objects and admin interfaces which you can use\nto create the hooks.\n\n* To create one for whole workflow regardless of what the workflow object is, go to\n\n    * ``/admin/river/onapprovedhook/`` to hook up to an approval\n    * ``/admin/river/ontransithook/`` to hook up to a transition\n    * ``/admin/river/oncompletehook/`` to hook up to the completion of the workflow\n\n* To create one for a specific workflow object you should use the admin interface for the workflow object itself. One amazing feature of ``django-river`` is now that it creates a default admin interface with the hookings for your workflow model class. If you have already defined one, ``django-river`` enriches your already defined admin with the hooking section. It is default disabled. To enable it just define ``RIVER_INJECT_MODEL_ADMIN`` to be ``True`` in the ``settings.py``.\n\n\n**Note:** They can programmatically be created as well since they are model objects. If it is needed to be at workflow level, just don't provide the workflow object column. If it is needed\nto be for a specific workflow object then provide it.\n\nHere are the list of hook models;\n\n* OnApprovedHook\n* OnTransitHook\n* OnCompleteHook\n\nBefore Reporting A Bug\n----------------------\n\n``django-river`` has behavioral tests that are very easy to read and write. One can easily set up one\nand see if everything is running as expected. Please look at other examples (that are the files with ``.feature`` postfix)\nunder ``features`` folder that you can get all the inspiration and create one for yourself before you open an issue\nThen refer to your behavioral test to point out what is not function as expected to speed the process up for your own\nsake. It is even better to name it with your issue number so we can persist it in the repository.\n\nMigrations\n----------\n\n2.X.X to 3.0.0\n^^^^^^^^^^^^^^\n\n``django-river`` v3.0.0 comes with quite number of migrations, but the good news is that even though those are hard to determine kind of migrations, it comes with the required migrations\nout of the box. All you need to do is to run;\n\n\n   .. code:: bash\n\n       python manage.py migrate river\n\n3.1.X to 3.2.X\n^^^^^^^^^^^^^^\n\n``django-river`` started to support **Microsoft SQL Server 17 and 19** after version 3.2.0 but the previous migrations didn't get along with it. We needed to reset all\nthe migrations to have fresh start. If you have already migrated to version `3.1.X` all you need to do is to pull your migrations back to the beginning.\n\n\n   .. code:: bash\n\n       python manage.py migrate --fake river zero\n       python manage.py migrate --fake river\n\nFAQ\n---\n\nHave a look at `FAQ`_\n\n.. _`FAQ`: https://django-river.readthedocs.io/en/latest/faq.html\n\nContributors\n============\n\nCode Contributors\n------------------\n\nThis project exists thanks to all the people who contribute :rocket: :heart:\n\n.. image:: https://opencollective.com/django-river/contributors.svg?width=890\u0026button=false\n    :target: https://github.com/javrasya/django-river/graphs/contributors\n\nFinancial Contributors\n----------------------\n\nBecome a financial contributor and help us sustain our community. Contribute_\n\nIndividuals\n^^^^^^^^^^^\n\n.. image:: https://opencollective.com/django-river/individuals.svg?width=890\n    :target: https://opencollective.com/django-river\n\nOrganizations\n^^^^^^^^^^^^^\n\nSupport this project with your organization. Your logo will show up here with a link to your website. Contribute_\n\n.. image:: https://opencollective.com/django-river/organization/0/avatar.svg\n    :target: https://opencollective.com/django-river/organization/0/website\n\n.. _Contribute: https://opencollective.com/django-river\n\n.. _license:\n\nLicense\n=======\n\nThis software is licensed under the `New BSD License`. See the ``LICENSE``\nfile in the top distribution directory for the full license text.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjavrasya%2Fdjango-river","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjavrasya%2Fdjango-river","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjavrasya%2Fdjango-river/lists"}