django fsm data immutability support
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
FreezableFSMModelMixinto your django-fsm model - Specify the
FROZEN_IN_STATESin which the object should be frozen, meaning the value of its fields/attributes cannot be changed. - (optional) Customize the
NON_FROZEN_FIELDSfor 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)
| File | Size | Uploaded | |
|---|---|---|---|
| django-fsm-freeze-0.1.9.tar.gz | 6.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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
|