Skip to main content

django fsm data immutability support

CI PyPI version Downloads

django-fsm-freeze provides a django model mixin for data immutability based on django-fsm.

Installation

pip install django-fsm-freeze

Configuration

Basic configuration

  • Add FreezableFSMModelMixin to your django-fsm model
  • Specify the FROZEN_IN_STATES in which the object should be frozen, meaning the value of its fields/attributes cannot be changed.
  • (optional) Customize the NON_FROZEN_FIELDS for partial mutability

When an object is in a frozen state, by default all of its fields are immutable, except for the state FSMField which needs to be mutable for django-fsm to work.

from django_fsm import FSMField

from django_fsm_freeze.models import FreezableFSMModelMixin

class MyDjangoFSMModel(FreezableFSMModelMixin):

    # In this example, when object is in the 'active' state, it is immutable.
    FROZEN_IN_STATES = ('active', )
    
    # django-fsm specifics: state, transitions, etc.
    state = FSMField(default='new')
    # ...

Customization

Tell django-fsm-freeze which field to look up for frozeness

By default, FreezableFSMModelMixin will look for the FSMField on your model and its value to determine whether the instance is frozen or not. However, in case your model has multiple FSMFields, you would need to tell the Mixin which field should be used to look up, to determine the frozeness via the FROZEN_STATE_LOOKUP_FIELD attribute.

from django.db import models
from django_fsm import FSMField

from django_fsm_freeze.models import FreezableFSMModelMixin

class MyDjangoFSMModel(FreezableFSMModelMixin):

    # In this example, when object is in the 'active' state, it is immutable.
    FROZEN_IN_STATES = ('active', )

    # Assign this with the name of the `FSMField` if your models has multiple FSMFields.
    # See example in `mytest/models.py:FakeModel2`
    FROZEN_STATE_LOOKUP_FIELD = 'state'
    
    # django-fsm specifics: state, transitions, etc.
    state = FSMField(default='new')
    another_state = FSMField(default='draft')
    # ...

In another case, when the desired lookup state is on another model related via foreign key, instead of setting FROZEN_STATE_LOOKUP_FIELD, it is possible to specify the (dot-separated) path to that field in FROZEN_DELEGATE_TO. This setting instructs the freezable model instance to evaluate the freezable state from that remote field.

class Parent(FreezableFSMModelMixin):
    state = FSMField(default='new')


class Child(FreezableFSMModelMixin):

    # Assign this with the path (dotted separated) to the instance you expect
    # the decision for freezability to be decided on.
    FROZEN_DELEGATE_TO = 'parent'
    parent = models.ForeignKey(Parent, on_delete=models.PROTECT)

Define for partial mutability

In case we want to mutate certain fields when the object is frozen, we can set the NON_FROZEN_FIELDS to allow it.

class MyDjangoFSMModel(FreezableFSMModelMixin):

    # In this example, when object is in the 'active' state, it is immutable.
    FROZEN_IN_STATES = ('active', )
    NON_FROZEN_FIELDS = ('a_mutable_field', )

    # This field is mutable even when the object is in the frozen state.
    a_mutable_field = models.BooleanField()

See configuration example in https://github.com/ming-tung/django-fsm-freeze/blob/main/mytest/models.py

Usage

The frozen check takes place when

  • class is prepared (configuration checking)
  • object.save()
  • object.delete()

In case of trying to save/delete a frozen object, a FreezeValidationError will be raised. In case of misconfiguration, a FreezeConfigurationError will be raised.

Bypassing

If you want to bypass the frozen check for some reason, you can use the contextmanager bypass_fsm_freeze(), with the freezable object(s) that you want to bypass the checks on, or apply the bypass globally via bypass_globally argument.

You can find some usage example in test mytest/test_models.py:TestBypassFreezeCheck.

Developing

For contributors or developers of the project, please see DEVELOPING.md

Contributing

(TODO) For anyone who is interested in contributing to this project, please see CONTRIBUTING.md. Thank you :)

For further discussions or suggestions, you could also reach out to me on twitter or email.

Metadata

Release files for django-fsm-freeze 0.1.9

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for django-fsm-freeze 0.1.9
File Size Uploaded
django-fsm-freeze-0.1.9.tar.gz 6.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for django-fsm-freeze 0.1.9
File Interpreter ABI Platform
django_fsm_freeze-0.1.9-py3-none-any.whl Python 3 none any Details

Total release size: 12.8 kB

Release files / django-fsm-freeze-0.1.9.tar.gz

Download URL django-fsm-freeze-0.1.9.tar.gz
Size 6.4 kB
Tags Source
SHA-256 checksum
How to use checksums
85a9fe3ef989390c9903b070a208714a7e54f2293dd767ffc828663b585e6234
BLAKE2b-256 checksum
How to use checksums
9b820e93b5acb422a73774b67e13d5187dd2711f1bb6fc10956756486a52675c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.1.8 CPython/3.9.6 Linux/5.8.0-1039-azure

Release files / django_fsm_freeze-0.1.9-py3-none-any.whl

Download URL django_fsm_freeze-0.1.9-py3-none-any.whl
Size 6.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5e8bba7be682b6c1b5e7f17aed68e2b71a653e11efe24094583b06853ee0fc45
BLAKE2b-256 checksum
How to use checksums
78e47d7e2a17a2dc33493c203b26d21e173a57ab1c0597ed7c6f1df48d7860aa
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/1.1.8 CPython/3.9.6 Linux/5.8.0-1039-azure

Release history Release notifications | RSS feed

This release

0.1.9 This release

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page