|pypi| |actions| |codecov| |downloads| |clinicedc|
django-revision
===============
Add a Django field class to your models to track a revision number with every model instance saved.
python 3.12+, Django 5.2+. Uses `GitPython`.
Required for research trials
----------------------------
For research trial data, you need to track the source code revision at time of data collection and modification. For example, if you deploy your live Django project from a cloned git branch, ``django-revision`` picks up the tag:branch:commit and updates each saved model instance as data is collected. If you are not using a cloned repository, ``django-revision`` can discover the revision number from other sources as described below.
When used with `django-simple-history`_, you can trace the revision number through all modifications of a model instance.
Installation
------------
Add to settings:
.. code-block:: python
INSTALLED_APPS = [
# ...
'django_revision.apps.AppConfig',
# ...
]
Add a revision field to your models
-----------------------------------
For example:
.. code-block:: python
from django.db import models
from simple_history.models import HistoricalRecords
from django_revision import RevisionField
class TestModel(models.Model):
revision = RevisionField()
history = HistoricalRecord()
or use the ``RevisionModelMixin``:
.. code-block:: python
from django.db import models
from simple_history.models import HistoricalRecords
from django_revision.model_mixins import RevisionField
class TestModel(RevisionModelMixin, models.Model):
history = HistoricalRecord()
then create or save a model instance
.. code-block:: text
>>> test_model = TestModel.objects.create()
>>> test_model.revision
'0.1dev0'
If the source is modified after the git tag was applied:
.. code-block:: text
>>> test_model = TestModel.objects.create()
>>> test_model.revision
'0.1dev0-35-ge9f632e:develop:e9f632e92143c53411290b576487f48c15156603'
How django-revision discovers the revision number
-------------------------------------------------
``django-revision`` was originally developed to discover the git tag when a django project is run from a cloned git repository. By default, an exception will be raised if the working directory is not a git repository. However this behaviour can be bypassed by telling ``django-revision`` to ignore git discovery. ``django-revision`` will then try to discover a revision number from other sources. If all sources fail, an exception is raised.
The ``revision`` number is discovered in this order:
1. from the git tag if working directory is a git repository
2. from package metadata ``version()``
3. from ``[project][version]`` from ``pyproject.toml``, if it exists
4. from ``VERSION``, if it exists
5. from ``settings.REVISION``
If the project using ``django-revision`` is not run from a git repo an exception will be raised by default. To bypass git discovery, update settings:
.. code-block:: python
DJANGO_REVISION_IGNORE_WORKING_DIR = True
Discovery will now walk through the remaining options until one returns a value. To skip any one of the remaining options, update settings:
.. code-block:: python
DJANGO_REVISION_IGNORE_METADATA = True
and / or
.. code-block:: python
DJANGO_REVISION_IGNORE_TOML_FILE = True
and / or
.. code-block:: python
DJANGO_REVISION_IGNORE_VERSION_FILE = True
You can hardcode a revision in settings as well (although this is not recommended):
.. code-block:: python
REVISION = "1.0.0"
or
.. code-block:: python
DJANGO_REVISION_REVISION = "1.0.0"
The ``settings.REVISION`` attribute is only used if the other options return ``None`` or you have told ``django-revision`` to ignore the other discovery options as shown above.
Relying on settings.REVISION
----------------------------
Hard coding ``settings.REVISION`` or ``settings. DJANGO_REVISION_REVISION`` is not recommended since you might forget to update the value and tag your data instances with the wrong revision number.
Using a git folder other than settings.BASE_DIR
-----------------------------------------------
By default, the git working directory is expected to be the same as settings.BASE_DIR. If not, add ``settings.GIT_DIR`` to ``settings`` with the path to your `git` working directory. For example:
.. code-block:: python
GIT_DIR = Path(BASE_DIR).parent.parent
Using in a View and Template
----------------------------
In the view's ``get_context_data`` set a context attribute to ``revision.tag`` or just use the ``RevisionMixin``:
.. code-block:: python
from django_revision.views import RevisionMixin
class MyView(RevisionMixin, TemplateView):
pass
In your template:
.. code-block:: text
{% block footer %}
<footer class="footer">
<div class="container">
<div class="col-md-4"><p class="text-muted text-center"><small>{{ year }} {{ institution }}</small></p></div>
<div class="col-md-4"><p class="text-muted text-center"><small>Revision: {{ revision }}</small></p></div>
<div class="col-md-4"><p class="text-muted text-center"><small>For Research Purposes Only</small></p></div>
</div>
</footer>
{% endblock footer %}
.. |pypi| image:: https://img.shields.io/pypi/v/django-revision.svg
:target: https://pypi.python.org/pypi/django-revision
.. |actions| image:: https://github.com/erikvw/django-revision/workflows/build/badge.svg?branch=develop
:target: https://github.com/erikvw/django-revision/actions?query=workflow:build
.. |codecov| image:: https://codecov.io/gh/erikvw/django-revision/branch/develop/graph/badge.svg
:target: https://codecov.io/gh/erikvw/django-revision
.. |downloads| image:: https://pepy.tech/badge/django-revision
:target: https://pepy.tech/project/django-revision
.. |clinicedc| image:: https://img.shields.io/badge/framework-Clinic_EDC-green
:alt:Made with clinicedc
:target: https://github.com/clinicedc
.. _django-simple-history: https://github.com/django-commons/django-simple-history
Raw data
{
"_id": null,
"home_page": null,
"name": "django-revision",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.12",
"maintainer_email": null,
"keywords": "Django, git, revision, clinicedc, edc",
"author": "Erik van Widenfelt",
"author_email": "Erik van Widenfelt <ew2789@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/6f/d1/9764a77133dbf6e0121abdb06aec57495929f900ea6f0fca6025899df75b/django_revision-2.0.0.tar.gz",
"platform": null,
"description": "|pypi| |actions| |codecov| |downloads| |clinicedc|\n\ndjango-revision\n===============\n\nAdd a Django field class to your models to track a revision number with every model instance saved.\n\npython 3.12+, Django 5.2+. Uses `GitPython`.\n\nRequired for research trials\n----------------------------\nFor research trial data, you need to track the source code revision at time of data collection and modification. For example, if you deploy your live Django project from a cloned git branch, ``django-revision`` picks up the tag:branch:commit and updates each saved model instance as data is collected. If you are not using a cloned repository, ``django-revision`` can discover the revision number from other sources as described below.\n\nWhen used with `django-simple-history`_, you can trace the revision number through all modifications of a model instance.\n\nInstallation\n------------\n\nAdd to settings:\n\n.. code-block:: python\n\n INSTALLED_APPS = [\n # ...\n 'django_revision.apps.AppConfig',\n # ...\n ]\n\nAdd a revision field to your models\n-----------------------------------\n\nFor example:\n\n.. code-block:: python\n\n from django.db import models\n from simple_history.models import HistoricalRecords\n from django_revision import RevisionField\n\n class TestModel(models.Model):\n revision = RevisionField()\n history = HistoricalRecord()\n\n\nor use the ``RevisionModelMixin``:\n\n\n.. code-block:: python\n\n from django.db import models\n from simple_history.models import HistoricalRecords\n from django_revision.model_mixins import RevisionField\n\n class TestModel(RevisionModelMixin, models.Model):\n history = HistoricalRecord()\n\n\nthen create or save a model instance\n\n\n.. code-block:: text\n\n >>> test_model = TestModel.objects.create()\n >>> test_model.revision\n '0.1dev0'\n\n\nIf the source is modified after the git tag was applied:\n\n.. code-block:: text\n\n >>> test_model = TestModel.objects.create()\n >>> test_model.revision\n '0.1dev0-35-ge9f632e:develop:e9f632e92143c53411290b576487f48c15156603'\n\n\nHow django-revision discovers the revision number\n-------------------------------------------------\n\n``django-revision`` was originally developed to discover the git tag when a django project is run from a cloned git repository. By default, an exception will be raised if the working directory is not a git repository. However this behaviour can be bypassed by telling ``django-revision`` to ignore git discovery. ``django-revision`` will then try to discover a revision number from other sources. If all sources fail, an exception is raised.\n\nThe ``revision`` number is discovered in this order:\n\n1. from the git tag if working directory is a git repository\n2. from package metadata ``version()``\n3. from ``[project][version]`` from ``pyproject.toml``, if it exists\n4. from ``VERSION``, if it exists\n5. from ``settings.REVISION``\n\nIf the project using ``django-revision`` is not run from a git repo an exception will be raised by default. To bypass git discovery, update settings:\n\n.. code-block:: python\n\n DJANGO_REVISION_IGNORE_WORKING_DIR = True\n\n\nDiscovery will now walk through the remaining options until one returns a value. To skip any one of the remaining options, update settings:\n\n\n.. code-block:: python\n\n DJANGO_REVISION_IGNORE_METADATA = True\n\nand / or\n\n.. code-block:: python\n\n DJANGO_REVISION_IGNORE_TOML_FILE = True\n\nand / or\n\n.. code-block:: python\n\n DJANGO_REVISION_IGNORE_VERSION_FILE = True\n\n\nYou can hardcode a revision in settings as well (although this is not recommended):\n\n.. code-block:: python\n\n REVISION = \"1.0.0\"\n\nor\n\n.. code-block:: python\n\n DJANGO_REVISION_REVISION = \"1.0.0\"\n\n\nThe ``settings.REVISION`` attribute is only used if the other options return ``None`` or you have told ``django-revision`` to ignore the other discovery options as shown above.\n\nRelying on settings.REVISION\n----------------------------\nHard coding ``settings.REVISION`` or ``settings. DJANGO_REVISION_REVISION`` is not recommended since you might forget to update the value and tag your data instances with the wrong revision number.\n\n\nUsing a git folder other than settings.BASE_DIR\n-----------------------------------------------\nBy default, the git working directory is expected to be the same as settings.BASE_DIR. If not, add ``settings.GIT_DIR`` to ``settings`` with the path to your `git` working directory. For example:\n\n.. code-block:: python\n\n GIT_DIR = Path(BASE_DIR).parent.parent\n\nUsing in a View and Template\n----------------------------\n\nIn the view's ``get_context_data`` set a context attribute to ``revision.tag`` or just use the ``RevisionMixin``:\n\n.. code-block:: python\n\n from django_revision.views import RevisionMixin\n\n class MyView(RevisionMixin, TemplateView):\n pass\n\nIn your template:\n\n.. code-block:: text\n\n {% block footer %}\n <footer class=\"footer\">\n <div class=\"container\">\n <div class=\"col-md-4\"><p class=\"text-muted text-center\"><small>{{ year }} {{ institution }}</small></p></div>\n <div class=\"col-md-4\"><p class=\"text-muted text-center\"><small>Revision: {{ revision }}</small></p></div>\n <div class=\"col-md-4\"><p class=\"text-muted text-center\"><small>For Research Purposes Only</small></p></div>\n </div>\n </footer>\n {% endblock footer %}\n\n.. |pypi| image:: https://img.shields.io/pypi/v/django-revision.svg\n :target: https://pypi.python.org/pypi/django-revision\n\n.. |actions| image:: https://github.com/erikvw/django-revision/workflows/build/badge.svg?branch=develop\n :target: https://github.com/erikvw/django-revision/actions?query=workflow:build\n\n.. |codecov| image:: https://codecov.io/gh/erikvw/django-revision/branch/develop/graph/badge.svg\n :target: https://codecov.io/gh/erikvw/django-revision\n\n.. |downloads| image:: https://pepy.tech/badge/django-revision\n :target: https://pepy.tech/project/django-revision\n\n.. |clinicedc| image:: https://img.shields.io/badge/framework-Clinic_EDC-green\n :alt:Made with clinicedc\n :target: https://github.com/clinicedc\n\n.. _django-simple-history: https://github.com/django-commons/django-simple-history\n",
"bugtrack_url": null,
"license": null,
"summary": "Track the git revision with every model instance saved",
"version": "2.0.0",
"project_urls": {
"Changelog": "https://github.com/erikvw/django-revision/blob/main/CHANGES",
"Documentation": "https://github.com/erikvw/django-revision/blob/README.rst",
"Homepage": "https://github.com/erikvw/django-revision",
"Repository": "https://github.com/erikvw/django-revision.git"
},
"split_keywords": [
"django",
" git",
" revision",
" clinicedc",
" edc"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "7c82c30c2c2be3c9c311e70d146afb387e097e1d114bfe192211ce840970f376",
"md5": "a402d3640029e65f9cc67e9cff78e167",
"sha256": "085a04d18bfa0682b1cf3fd307698617473443f6fd88704df3982b9c58adf00c"
},
"downloads": -1,
"filename": "django_revision-2.0.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "a402d3640029e65f9cc67e9cff78e167",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.12",
"size": 20075,
"upload_time": "2025-08-17T22:32:32",
"upload_time_iso_8601": "2025-08-17T22:32:32.331860Z",
"url": "https://files.pythonhosted.org/packages/7c/82/c30c2c2be3c9c311e70d146afb387e097e1d114bfe192211ce840970f376/django_revision-2.0.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "6fd19764a77133dbf6e0121abdb06aec57495929f900ea6f0fca6025899df75b",
"md5": "dc2e9136cf6a5ad333915326f84255e5",
"sha256": "285d8a491955f2c63629de5738bd9db3199b7caa01fd2b8aedae7816a3a0eda8"
},
"downloads": -1,
"filename": "django_revision-2.0.0.tar.gz",
"has_sig": false,
"md5_digest": "dc2e9136cf6a5ad333915326f84255e5",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.12",
"size": 15108,
"upload_time": "2025-08-17T22:32:33",
"upload_time_iso_8601": "2025-08-17T22:32:33.661595Z",
"url": "https://files.pythonhosted.org/packages/6f/d1/9764a77133dbf6e0121abdb06aec57495929f900ea6f0fca6025899df75b/django_revision-2.0.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-17 22:32:33",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "erikvw",
"github_project": "django-revision",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"tox": true,
"lcname": "django-revision"
}