django-fsm-log


Namedjango-fsm-log JSON
Version 3.1.0 PyPI version JSON
download
home_pagehttps://github.com/jazzband/django-fsm-log
SummaryTransition's persistence for django-fsm
upload_time2023-03-23 16:49:35
maintainer
docs_urlNone
authorGizmag
requires_python
licenseMIT
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Django Finite State Machine Log

[![test suite](https://github.com/jazzband/django-fsm-log/actions/workflows/test_suite.yml/badge.svg)](https://github.com/jazzband/django-fsm-log/actions/workflows/test_suite.yml)
[![codecov](https://codecov.io/gh/jazzband/django-fsm-log/branch/master/graph/badge.svg)](https://codecov.io/gh/jazzband/django-fsm-log)
[![Jazzband](https://jazzband.co/static/img/badge.svg)](https://jazzband.co/)
[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/jazzband/django-fsm-log/master.svg)](https://results.pre-commit.ci/latest/github/jazzband/django-fsm-log/master)
[![Documentation Status](https://readthedocs.org/projects/django-fsm-log/badge/?version=latest)](https://django-fsm-log.readthedocs.io/en/latest/?badge=latest)

Provides persistence of the transitions of your fsm's models. Backed by the excellent [Django FSM](https://github.com/viewflow/django-fsm)
package.

Logs can be accessed before a transition occurs and before they are persisted to the database
by enabling a cached backend. See [Advanced Usage](#advanced-usage)

## Changelog

## 4.0.0 (not released)

## 3.1.0 (2023-03-23)

- `fsm_log_description` now accepts a default description parameter
- Document `fsm_log_description` decorator
- Add support for Django 4.1
- Add compatibility for python 3.11

### 3.0.0 (2022-01-14)

- Switch to github actions (from travis-ci)
- Test against django 3.2 and 4.0, then python 3.9 and 3.10
- Drop support for django 1.11, 2.0, 2.1, 3.0, 3.1
- Drop support for python 3.4, 3.5, 3.6
- allow using StateLogManager in migrations [#95](https://github.com/jazzband/django-fsm-log/pull/95)

### 2.0.1 (2020-03-26)

- Add support for django3.0
- Drop support for python2

### 1.6.2 (2019-01-06)

- Address Migration history breakage added in 1.6.1

### 1.6.1 (2018-12-02)

- Make StateLog.description field nullable

### 1.6.0 (2018-11-14)

- Add source state on transitions
- Fixed `get_state_display` with FSMIntegerField (#63)
- Fixed handling of transitions if target is None (#71)
- Added `fsm_log_description` decorator (#1, #67)
- Dropped support for Django 1.10 (#64)

### 1.5.0 (2017-11-29)

- cleanup deprecated code.
- add codecov support.
- switch to pytest.
- add Admin integration to visualize past transitions.

### 1.4.0 (2017-11-09)

- Bring compatibility with Django 2.0 and drop support of unsupported versions
  of Django: `1.6`, `1.7`, `1.9`.

### Compatibility

- Python 2.7 and 3.4+
- Django 1.8+
- Django-FSM 2+

## Installation

First, install the package with pip. This will automatically install any
dependencies you may be missing

```bash
pip install django-fsm-log
```

Register django_fsm_log in your list of Django applications:

```python
INSTALLED_APPS = (
    ...,
    'django_fsm_log',
    ...,
)
```

Then migrate the app to create the database table

```bash
python manage.py migrate django_fsm_log
```

## Usage

The app listens for the `django_fsm.signals.post_transition` signal and
creates a new record for each transition.

To query the log:

```python
from django_fsm_log.models import StateLog
StateLog.objects.all()
# ...all recorded logs...
```

### Disabling logging for specific models

By default transitions get recorded for all models. Logging can be disabled for
specific models by adding their fully qualified name to `DJANGO_FSM_LOG_IGNORED_MODELS`.

```python
DJANGO_FSM_LOG_IGNORED_MODELS = ('poll.models.Vote',)
```

### `for_` Manager Method

For convenience there is a custom `for_` manager method to easily filter on the generic foreign key:

```python
from my_app.models import Article
from django_fsm_log.models import StateLog

article = Article.objects.all()[0]

StateLog.objects.for_(article)
# ...logs for article...
```

### `by` Decorator

We found that our transitions are commonly called by a user, so we've added a
decorator to make logging this easy:

```python
from django.db import models
from django_fsm import FSMField, transition
from django_fsm_log.decorators import fsm_log_by

class Article(models.Model):

    state = FSMField(default='draft', protected=True)

    @fsm_log_by
    @transition(field=state, source='draft', target='submitted')
    def submit(self, by=None):
        pass
```

With this the transition gets logged when the `by` kwarg is present.

```python
article = Article.objects.create()
article.submit(by=some_user) # StateLog.by will be some_user
```

### `description` Decorator

Decorator that allows to set a custom description (saved on database) to a transitions.

```python
from django.db import models
from django_fsm import FSMField, transition
from django_fsm_log.decorators import fsm_log_description

class Article(models.Model):

    state = FSMField(default='draft', protected=True)

    @fsm_log_description(description='Article submitted')  # description param is NOT required
    @transition(field=state, source='draft', target='submitted')
    def submit(self, description=None):
        pass

article = Article.objects.create()
article.submit()  # logged with "Article submitted" description
article.submit(description="Article reviewed and submitted")  # logged with "Article reviewed and submitted" description
```

.. TIP::
    The "description" argument passed when calling ".submit" has precedence over the default description set in the decorator

The decorator also accepts a `allow_inline` boolean argument that allows to set the description inside the transition method.

```python
from django.db import models
from django_fsm import FSMField, transition
from django_fsm_log.decorators import fsm_log_description

class Article(models.Model):

    state = FSMField(default='draft', protected=True)

    @fsm_log_description(allow_inline=True)
    @transition(field=state, source='draft', target='submitted')
    def submit(self, description=None):
        description.set("Article submitted")

article = Article.objects.create()
article.submit()  # logged with "Article submitted" description
```

### Admin integration

There is an InlineForm available that can be used to display the history of changes.

To use it expand your own `AdminModel` by adding `StateLogInline` to its inlines:

```python
from django.contrib import admin
from django_fsm_log.admin import StateLogInline


@admin.register(FSMModel)
class FSMModelAdmin(admin.ModelAdmin):
    inlines = [StateLogInline]
```

### Advanced Usage

You can change the behaviour of this app by turning on caching for StateLog records.
Simply add `DJANGO_FSM_LOG_STORAGE_METHOD = 'django_fsm_log.backends.CachedBackend'` to your project's settings file.
It will use your project's default cache backend by default. If you wish to use a specific cache backend, you can add to
your project's settings:

```python
DJANGO_FSM_LOG_CACHE_BACKEND = 'some_other_cache_backend'
```

The StateLog object is now available after the `django_fsm.signals.pre_transition`
signal is fired, but is deleted from the cache and persisted to the database after `django_fsm.signals.post_transition`
is fired.

This is useful if:

- you need immediate access to StateLog details, and cannot wait until `django_fsm.signals.post_transition`
has been fired
- at any stage, you need to verify whether or not the StateLog has been written to the database

Access to the pending StateLog record is available via the `pending_objects` manager

```python
from django_fsm_log.models import StateLog
article = Article.objects.get(...)
pending_state_log = StateLog.pending_objects.get_for_object(article)
```

## Contributing

### Running tests

```bash
pip install tox
tox
```

### Linting with pre-commit

We use ruff, black and more, all configured and check via [pre-commit](https://pre-commit.com/).
Before committing, run the following:

```bash
pip install pre-commit
pre-commit install
```



            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/jazzband/django-fsm-log",
    "name": "django-fsm-log",
    "maintainer": "",
    "docs_url": null,
    "requires_python": "",
    "maintainer_email": "",
    "keywords": "",
    "author": "Gizmag",
    "author_email": "tech@gizmag.com",
    "download_url": "https://files.pythonhosted.org/packages/bd/25/25296d04f9d4bb3717049a4f758f8b3ce5c6614ffea3b9504d1f6e79121f/django-fsm-log-3.1.0.tar.gz",
    "platform": null,
    "description": "# Django Finite State Machine Log\n\n[![test suite](https://github.com/jazzband/django-fsm-log/actions/workflows/test_suite.yml/badge.svg)](https://github.com/jazzband/django-fsm-log/actions/workflows/test_suite.yml)\n[![codecov](https://codecov.io/gh/jazzband/django-fsm-log/branch/master/graph/badge.svg)](https://codecov.io/gh/jazzband/django-fsm-log)\n[![Jazzband](https://jazzband.co/static/img/badge.svg)](https://jazzband.co/)\n[![pre-commit.ci status](https://results.pre-commit.ci/badge/github/jazzband/django-fsm-log/master.svg)](https://results.pre-commit.ci/latest/github/jazzband/django-fsm-log/master)\n[![Documentation Status](https://readthedocs.org/projects/django-fsm-log/badge/?version=latest)](https://django-fsm-log.readthedocs.io/en/latest/?badge=latest)\n\nProvides persistence of the transitions of your fsm's models. Backed by the excellent [Django FSM](https://github.com/viewflow/django-fsm)\npackage.\n\nLogs can be accessed before a transition occurs and before they are persisted to the database\nby enabling a cached backend. See [Advanced Usage](#advanced-usage)\n\n## Changelog\n\n## 4.0.0 (not released)\n\n## 3.1.0 (2023-03-23)\n\n- `fsm_log_description` now accepts a default description parameter\n- Document `fsm_log_description` decorator\n- Add support for Django 4.1\n- Add compatibility for python 3.11\n\n### 3.0.0 (2022-01-14)\n\n- Switch to github actions (from travis-ci)\n- Test against django 3.2 and 4.0, then python 3.9 and 3.10\n- Drop support for django 1.11, 2.0, 2.1, 3.0, 3.1\n- Drop support for python 3.4, 3.5, 3.6\n- allow using StateLogManager in migrations [#95](https://github.com/jazzband/django-fsm-log/pull/95)\n\n### 2.0.1 (2020-03-26)\n\n- Add support for django3.0\n- Drop support for python2\n\n### 1.6.2 (2019-01-06)\n\n- Address Migration history breakage added in 1.6.1\n\n### 1.6.1 (2018-12-02)\n\n- Make StateLog.description field nullable\n\n### 1.6.0 (2018-11-14)\n\n- Add source state on transitions\n- Fixed `get_state_display` with FSMIntegerField (#63)\n- Fixed handling of transitions if target is None (#71)\n- Added `fsm_log_description` decorator (#1, #67)\n- Dropped support for Django 1.10 (#64)\n\n### 1.5.0 (2017-11-29)\n\n- cleanup deprecated code.\n- add codecov support.\n- switch to pytest.\n- add Admin integration to visualize past transitions.\n\n### 1.4.0 (2017-11-09)\n\n- Bring compatibility with Django 2.0 and drop support of unsupported versions\n  of Django: `1.6`, `1.7`, `1.9`.\n\n### Compatibility\n\n- Python 2.7 and 3.4+\n- Django 1.8+\n- Django-FSM 2+\n\n## Installation\n\nFirst, install the package with pip. This will automatically install any\ndependencies you may be missing\n\n```bash\npip install django-fsm-log\n```\n\nRegister django_fsm_log in your list of Django applications:\n\n```python\nINSTALLED_APPS = (\n    ...,\n    'django_fsm_log',\n    ...,\n)\n```\n\nThen migrate the app to create the database table\n\n```bash\npython manage.py migrate django_fsm_log\n```\n\n## Usage\n\nThe app listens for the `django_fsm.signals.post_transition` signal and\ncreates a new record for each transition.\n\nTo query the log:\n\n```python\nfrom django_fsm_log.models import StateLog\nStateLog.objects.all()\n# ...all recorded logs...\n```\n\n### Disabling logging for specific models\n\nBy default transitions get recorded for all models. Logging can be disabled for\nspecific models by adding their fully qualified name to `DJANGO_FSM_LOG_IGNORED_MODELS`.\n\n```python\nDJANGO_FSM_LOG_IGNORED_MODELS = ('poll.models.Vote',)\n```\n\n### `for_` Manager Method\n\nFor convenience there is a custom `for_` manager method to easily filter on the generic foreign key:\n\n```python\nfrom my_app.models import Article\nfrom django_fsm_log.models import StateLog\n\narticle = Article.objects.all()[0]\n\nStateLog.objects.for_(article)\n# ...logs for article...\n```\n\n### `by` Decorator\n\nWe found that our transitions are commonly called by a user, so we've added a\ndecorator to make logging this easy:\n\n```python\nfrom django.db import models\nfrom django_fsm import FSMField, transition\nfrom django_fsm_log.decorators import fsm_log_by\n\nclass Article(models.Model):\n\n    state = FSMField(default='draft', protected=True)\n\n    @fsm_log_by\n    @transition(field=state, source='draft', target='submitted')\n    def submit(self, by=None):\n        pass\n```\n\nWith this the transition gets logged when the `by` kwarg is present.\n\n```python\narticle = Article.objects.create()\narticle.submit(by=some_user) # StateLog.by will be some_user\n```\n\n### `description` Decorator\n\nDecorator that allows to set a custom description (saved on database) to a transitions.\n\n```python\nfrom django.db import models\nfrom django_fsm import FSMField, transition\nfrom django_fsm_log.decorators import fsm_log_description\n\nclass Article(models.Model):\n\n    state = FSMField(default='draft', protected=True)\n\n    @fsm_log_description(description='Article submitted')  # description param is NOT required\n    @transition(field=state, source='draft', target='submitted')\n    def submit(self, description=None):\n        pass\n\narticle = Article.objects.create()\narticle.submit()  # logged with \"Article submitted\" description\narticle.submit(description=\"Article reviewed and submitted\")  # logged with \"Article reviewed and submitted\" description\n```\n\n.. TIP::\n    The \"description\" argument passed when calling \".submit\" has precedence over the default description set in the decorator\n\nThe decorator also accepts a `allow_inline` boolean argument that allows to set the description inside the transition method.\n\n```python\nfrom django.db import models\nfrom django_fsm import FSMField, transition\nfrom django_fsm_log.decorators import fsm_log_description\n\nclass Article(models.Model):\n\n    state = FSMField(default='draft', protected=True)\n\n    @fsm_log_description(allow_inline=True)\n    @transition(field=state, source='draft', target='submitted')\n    def submit(self, description=None):\n        description.set(\"Article submitted\")\n\narticle = Article.objects.create()\narticle.submit()  # logged with \"Article submitted\" description\n```\n\n### Admin integration\n\nThere is an InlineForm available that can be used to display the history of changes.\n\nTo use it expand your own `AdminModel` by adding `StateLogInline` to its inlines:\n\n```python\nfrom django.contrib import admin\nfrom django_fsm_log.admin import StateLogInline\n\n\n@admin.register(FSMModel)\nclass FSMModelAdmin(admin.ModelAdmin):\n    inlines = [StateLogInline]\n```\n\n### Advanced Usage\n\nYou can change the behaviour of this app by turning on caching for StateLog records.\nSimply add `DJANGO_FSM_LOG_STORAGE_METHOD = 'django_fsm_log.backends.CachedBackend'` to your project's settings file.\nIt will use your project's default cache backend by default. If you wish to use a specific cache backend, you can add to\nyour project's settings:\n\n```python\nDJANGO_FSM_LOG_CACHE_BACKEND = 'some_other_cache_backend'\n```\n\nThe StateLog object is now available after the `django_fsm.signals.pre_transition`\nsignal is fired, but is deleted from the cache and persisted to the database after `django_fsm.signals.post_transition`\nis fired.\n\nThis is useful if:\n\n- you need immediate access to StateLog details, and cannot wait until `django_fsm.signals.post_transition`\nhas been fired\n- at any stage, you need to verify whether or not the StateLog has been written to the database\n\nAccess to the pending StateLog record is available via the `pending_objects` manager\n\n```python\nfrom django_fsm_log.models import StateLog\narticle = Article.objects.get(...)\npending_state_log = StateLog.pending_objects.get_for_object(article)\n```\n\n## Contributing\n\n### Running tests\n\n```bash\npip install tox\ntox\n```\n\n### Linting with pre-commit\n\nWe use ruff, black and more, all configured and check via [pre-commit](https://pre-commit.com/).\nBefore committing, run the following:\n\n```bash\npip install pre-commit\npre-commit install\n```\n\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "Transition's persistence for django-fsm",
    "version": "3.1.0",
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "960d45936561ddef8a714d08acfa74a72d5e0b0d4f4775cec78b4cea8b33fd24",
                "md5": "e11323a20b61ad90b294134797df87f9",
                "sha256": "ac4394f22659e7fb8e5ac42d1cc075490cd5a2af37202377ab2a1cb221c5f3db"
            },
            "downloads": -1,
            "filename": "django_fsm_log-3.1.0-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "e11323a20b61ad90b294134797df87f9",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": null,
            "size": 14087,
            "upload_time": "2023-03-23T16:49:31",
            "upload_time_iso_8601": "2023-03-23T16:49:31.647469Z",
            "url": "https://files.pythonhosted.org/packages/96/0d/45936561ddef8a714d08acfa74a72d5e0b0d4f4775cec78b4cea8b33fd24/django_fsm_log-3.1.0-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "bd2525296d04f9d4bb3717049a4f758f8b3ce5c6614ffea3b9504d1f6e79121f",
                "md5": "67f22f42f9cee708b367d0a2413bd165",
                "sha256": "9ef766f5e6d7c573d1953cf91df73538a611373cc1ef97488eff19a3f71d6ed6"
            },
            "downloads": -1,
            "filename": "django-fsm-log-3.1.0.tar.gz",
            "has_sig": false,
            "md5_digest": "67f22f42f9cee708b367d0a2413bd165",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": null,
            "size": 211700,
            "upload_time": "2023-03-23T16:49:35",
            "upload_time_iso_8601": "2023-03-23T16:49:35.939280Z",
            "url": "https://files.pythonhosted.org/packages/bd/25/25296d04f9d4bb3717049a4f758f8b3ce5c6614ffea3b9504d1f6e79121f/django-fsm-log-3.1.0.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-03-23 16:49:35",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": "jazzband",
    "github_project": "django-fsm-log",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "tox": true,
    "lcname": "django-fsm-log"
}
        
Elapsed time: 0.11499s