Django Staskstore model
django-staskstore-model is a library that can support model versioning in a minimal amount of steps.
- Support Django 2 and 3
- Support Python3.7, 3.8 (Maybe 2.7. Not tested)
- Admin extensions are supported.
Usage
Model
# models.py
from stackstore.models import AbstractStackModel
class MySampleModel(AbstractStackModel):
title = models.CharField(
max_length=100,
null=False,
blank=False,
)
body = models.TextField(
max_length=1000,
null=False,
blank=False,
)
Python shell
# Create First version instance
>>> instance = MySampleModel.objects.create(title="Test", body="This is test text")
>>> instance.pk
1
# If you save this instance, create new version instance
>>> instance.title = "Test (version2)"
>>> instance.save()
>>> instance.pk
2
# If you can fetch previous version
>>> previous_instance = instance.previous_instance()
>>> previous_instance.pk
1
# You can get next version
>>> previous_instance.next_instance().pk
2
Admin Extension
Filter to show only the latest version of the object
Show only items with the same stackgroup_uuid
API
QuerySet & Manager
latest_from_stack_group
Returns a QuerySet of the most recent objects in each Stackgroup.
# Create instance
>>> instance_breakfast = MySampleModel.objects.create(title="Today's breakfast", body="Spam with Egg") # Create <MySampleModel: MySampleModel object (1)>
>>> instance_lunch = MySampleModel.objects.create(title="Today's lunch", body="Spam with Beacon") # Create <MySampleModel: MySampleModel object (2)>
# Save each instance
>>> instance_breakfast.body = "Fried Egg with bread"
>>> instance_breakfast.save() # Save method create new <MySampleModel: MySampleModel object (3)>
>>> instance_lunch.body = "Meat Pasta"
>>> instance_lunch.save() # Save method create new <MySampleModel: MySampleModel object (4)>
>>> MySampleModel.objects.latest_from_stack_group() # You can fetch 3 & 4 My Sample Model
<StackStoreQuerySet [<MySampleModel: MySampleModel object (3)>, <MySampleModel: MySampleModel object (4)>]>
get_latest_from_stack_group
Returns an object that matches the collation parameter from the latest set of objects in each Stackgroup.
# Create instance
>>> instance_breakfast = MySampleModel.objects.create(title="Today's breakfast", body="Spam with Egg") # Create <MySampleModel: MySampleModel object (1)>
>>> instance_lunch = MySampleModel.objects.create(title="Today's lunch", body="Spam with Beacon") # Create <MySampleModel: MySampleModel object (2)>
# Save each instance
>>> instance_breakfast.body = "Fried Egg with bread"
>>> instance_breakfast.save() # Save method create new <MySampleModel: MySampleModel object (3)>
>>> MySampleModel.objects.get_latest_from_stack_group(body="Fried Egg with bread")
<MySampleModel: MySampleModel object (3)>
model object
save
When an object is saved, a new object is created and assigned the same stack_group_uuid as the object from which it was saved. This means that a new version will be generated.
>>> instance_breakfast = MySampleModel.objects.create(title="Today's breakfast", body="Spam with Egg") # Create <MySampleModel: MySampleModel object (1)>
>>> instance_breakfast.body = "Fried Egg with bread"
>>> instance_breakfast.save() # Save method create version object <MySampleModel: MySampleModel object (2)>
>>> MySampleModel.objects.all()
<StackStoreQuerySet [<MySampleModel: MySampleModel object (1)>, <MySampleModel: MySampleModel object (2)>]>
If you want to save the overwrite without creating a new version, you should pass False to __create_new_version in the save method.
>>> instance_breakfast = MySampleModel.objects.create(title="Today's breakfast", body="Spam with Egg")
>>> instance_breakfast.save(__create_new_version=False)
>>> instance_breakfast.pk
1
force_delete
Remove the object.
>>> instance_breakfast = MySampleModel.objects.create(title="Today's breakfast", body="Spam with Egg") # Create <MySampleModel: MySampleModel object (1)>
>>> MySampleModel.objects.all()
<StackStoreQuerySet [<MySampleModel: MySampleModel object (1)>]>
>>> instance_breakfast.force_delete()
>>> MySampleModel.objects.all()
<StackStoreQuerySet []>
Calling the existing delete method will raise a NotImplementedError exception.
same_group_items
Returns a QuerySet that returns all objects belonging to the same Stackgroup.
>>> instance_breakfast = MySampleModel.objects.create(title="Today's breakfast", body="Spam with Egg") # Create <MySampleModel: MySampleModel object (1)>
>>> [instance_breakfast.save() for i in range(2)]
>>> instance_breakfast.same_group_items()
<StackStoreQuerySet [<MySampleModel: MySampleModel object (3)>, <MySampleModel: MySampleModel object (2)>, <MySampleModel: MySampleModel object (1)>]>
previous_instance
Returns the previous version of the object.
>>> instance_breakfast = MySampleModel.objects.create(title="Today's breakfast", body="Spam with Egg") # Create <MySampleModel: MySampleModel object (1)>
>>> [instance_breakfast.save() for i in range(2)]
>>> second_gen_instance = instance_breakfast.same_group_items().order_by("pk")[1]
>>> second_gen_instance.previous_instance()
<MySampleModel: MySampleModel object (1)>
Throws a DoesNotExist exception if the object does not exist.
next_instance
Returns the next version of the object.
>>> instance_breakfast = MySampleModel.objects.create(title="Today's breakfast", body="Spam with Egg") # Create <MySampleModel: MySampleModel object (1)>
>>> [instance_breakfast.save() for i in range(2)]
>>> second_gen_instance = instance_breakfast.same_group_items()[1]
>>> second_gen_instance.next_instance()
<MySampleModel: MySampleModel object (3)>
Throws a DoesNotExist exception if the object does not exist.
latest_instance
Returns the most recent object of the Stackgroup to which its own object belongs.
>>> instance_breakfast = MySampleModel.objects.create(title="Today's breakfast", body="Spam with Egg") # Create <MySampleModel: MySampleModel object (1)>
>>> [instance_breakfast.save() for i in range(2)]
>>> first_gen_instance = instance_breakfast.same_group_items().order_by("pk")[0]
>>> first_gen_instance.latest_instance()
<MySampleModel: MySampleModel object (3)>
Throws a DoesNotExist exception if the object does not exist.
earliest_instance
Returns the oldest object in the Stackgroup to which its own object belongs.
>>> instance_breakfast = MySampleModel.objects.create(title="Today's breakfast", body="Spam with Egg") # Create <MySampleModel: MySampleModel object (1)>
>>> [instance_breakfast.save() for i in range(2)]
>>> third_gen_instance = instance_breakfast.same_group_items().order_by("pk")[2]
>>> third_gen_instance.earliest_instance()
<MySampleModel: MySampleModel object (1)>
Throws a DoesNotExist exception if the object does not exist.
Demo
The Docker configuration is provided. Please use the following command to start it. Go to http://localhost:8000 when the launch is complete.
$ docker-compose up
Login account is ID: admin Password: admin
License
MIT License
Metadata
Release files for django-stackstore-model 0.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| django-stackstore-model-0.1.tar.gz | 4.7 kB | Without provenance | Details for django-stackstore-model-0.1.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| django_stackstore_model-0.1-py3-none-any.whl | Python 3 | none | any | Details for django_stackstore_model-0.1-py3-none-any.whl |
Total release size: 11.2 kB
Release files / django-stackstore-model-0.1.tar.gz
| Download URL | django-stackstore-model-0.1.tar.gz |
|---|---|
| Size | 4.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
4bf279e87ed38e7845f8de7ea06625d4cdb4944f3bf06d4adf06d78e95c4659a
|
|
BLAKE2b-256 checksum How to use checksums |
c6d5261be6b91a1498d6ec20312b883ec566b4ada9889db5b2f38b915ff108ab
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.8.2
|
Release files / django_stackstore_model-0.1-py3-none-any.whl
| Download URL | django_stackstore_model-0.1-py3-none-any.whl |
|---|---|
| Size | 6.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a864c8e5cb56357599883dea96dc0be33656b96e95dae9817fb877c631e136f8
|
|
BLAKE2b-256 checksum How to use checksums |
1577acf54ebef8b14080d67b73bc52bbe7d5ef895fc4de2bca27e3922c47845d
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/3.1.1 pkginfo/1.5.0.1 requests/2.23.0 setuptools/41.2.0 requests-toolbelt/0.9.1 tqdm/4.46.0 CPython/3.8.2
|
Security for django-stackstore-model 0.1
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.