Skip to main content

Track changes made to django model instance fields.

Project description

Django Tracking Model / DTM 🏁

Track changes made to your model's instance fields.
Changes are cleared on save.
This package works well with signals.
Mutable fields (e.g. JSONField) are not handled with deepcopy to keep it fast and simple.
Meant to be model_utils's FieldTracker fast alternative.

Available on PyPi

Installation

pip install django-tracking-model

Usage

from django.db import models
from tracking_model import TrackingModelMixin

# order matters
class Example(TrackingModelMixin, models.Model):
    text = models.TextField(null=True)
    myself = models.ForeignKey("self", null=True)
    array = models.ArrayField(TextField())
In [1]: e = Example.objects.create(id=1, text="Sample Text")
In [2]: e.tracker.changed, e.tracker.newly_created
Out[1]: ({}, True)

In [3]: e.text = "Different Text"
In [4]: e.tracker.changed
Out[2]: {"text": "Sample Text"}

In [5]: e.save()
In [6]: e.tracker.changed, e.tracker.newly_created
Out[3]: ({}, False)

DTM will also detect changes made to ForeignKey/OneToOne fields.

In [1]: Example.objects.create(myself=e)
In [2]: e.myself = None
In [3]: e.tracker.changed
Out[1]: {"myself_id": 1}

Because DTM does not handle mutable fields well, you handle them with copy/deepcopy.

In [1]: e = Example.objects.create(array=["I", "am", "your"])
In [2]: copied = copy(e.array)
In [3]: copied.append("father")
In [4]: e.array = copied
In [5]: e.tracker.changed
Out[1]: {"array": ["I", "am", "your"]}

In [6]: e.array = ["Testing", "is", "the", "future"]  # in this case copy not needed

DTM works best with *_save signals.

def pre_save_example(instance, *args, **kwargs):
    # .create() does not populate .changed, we use newly_created
    if "text" in instance.tracker.changed or instance.tracker.newly_created:
      if instance.text
          instance.array = instance.text.split()

pre_save.connect(pre_save_example, sender=Example)
In [1]: e = Example.objects.create(text="I am your father")
In [2]: e.refresh_from_db() # not needed
In [3]: e.array
Out[1]: ["I", "am", "your", "father"]

DTM handles deferred fields well.

In [1]: e = Example.objects.only("array").first()
In [2]: e.text = "I am not your father" 
In [3]: e.tracker.changed
Out[4]: {"text": DeferredAttribute}

You can narrow choice of tracked fields. By default everything is tracked.

class Example(models.Model):
    TRACKED_FIELDS = ["first"]
    first = models.TextField()
    second = models.TextField()

Requirements

  • Python >= 2.7, <= 3.11
  • Django >= 1.11, <= 4.x.y

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distributions

No source distribution files available for this release.See tutorial on generating distribution archives.

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

django_tracking_model-0.1.7-py2.py3-none-any.whl (4.3 kB view details)

Uploaded Python 2Python 3

File details

Details for the file django_tracking_model-0.1.7-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for django_tracking_model-0.1.7-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 719df534c450fbe841dd77e55f26fb69741723780add13ddb77961e90b64ec46
MD5 ea463c69217b0ae1a95ba12e5189fe53
BLAKE2b-256 d2dc90c2081ee1f8dd12995dde15dfadd23840b1a3f21e7be9af7e75ec6cf37f

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page