{ "info": { "author": "Andreas Stocker", "author_email": "andreas@ks.co.at", "bugtrack_url": null, "classifiers": [ "Environment :: Web Environment", "Framework :: Django", "Framework :: Django :: 1.11", "Framework :: Django :: 2.0", "Framework :: Django :: 2.1", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", "Programming Language :: Python :: 2", "Programming Language :: Python :: 2.7", "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.4", "Programming Language :: Python :: 3.5", "Programming Language :: Python :: 3.6", "Topic :: Internet :: WWW/HTTP", "Topic :: Internet :: WWW/HTTP :: Dynamic Content" ], "description": "================\nDjango ChangeSet\n================\n\n.. image:: https://travis-ci.org/beachmachine/django-changeset.svg?branch=master\n :target: https://travis-ci.org/beachmachine/django-changeset\n\nDjango ChangeSet is a simple Django app that will give your models the possibility to track all changes. It depends on\n``django_userforeignkey`` to determine the current user doing the change(s).\n\nCurrently, Django 1.11, 2.0 and 2.1 are supported and tested via travis-ci.\n\nDetailed documentation is in the docs subdirectory.\n\nQuick start\n-----------\n\n1. Use ``pip`` to install and download django-changeset (and ``django-userforeignkey``):\n\n.. code-block:: bash\n\n pip install django-changeset\n\n\n2. Add ``django_userforeignkey`` and ``django_changeset`` to your ``INSTALLED_APPS`` like this:\n\n.. code-block:: python\n\n INSTALLED_APPS = [\n ...\n 'django_userforeignkey',\n 'django_changeset',\n ]\n\n\n3. Add ``django_userforeignkey.middleware.UserForeignKeyMiddleware`` to your ``MIDDLEWARE`` like this:\n\n.. code-block:: python\n\n MIDDLEWARE = (\n ...\n 'django.contrib.auth.middleware.AuthenticationMiddleware',\n ...\n 'django_userforeignkey.middleware.UserForeignKeyMiddleware',\n )\n\n\n\n**Note**: Make sure to insert the ``UserForeignKeyMiddleware`` **after** Djangos ``AuthenticationMiddleware``.\n\n\nExample usage\n-------------\n\nUse ``RevisionModelMixin`` as a mixin class for your models and add the fields you want to track in the meta\n configuration using ``track_fields`` and ``track_related``. Also add a generic relation to ``ChangeSet`` using ``changesets = ChangeSetRelation()``:\n\n.. code-block:: python\n\n from django.db import models\n\n from django_changeset.models import RevisionModelMixin\n from django_changeset.models.fields import ChangeSetRelation\n\n\n class MyModel(models.Model, RevisionModelMixin):\n class Meta:\n track_fields = ('my_data', ) # track changes on my_data\n track_related = ('my_ref', ) # track changes on a related model\n\n my_data = models.CharField(max_length=64, verbose_name=\"Very important data you want to track\")\n my_ref = models.ForeignKey('SomeOtherModel', verbose_name=\"Very important relation\", related_name='my_models')\n\n # Generic Relation to ChangeSet\n changesets = ChangeSetRelation()\n\n\nNote: If you want to have access to the properties ``created_by``, ``created_at``, ``last_modified_by``, ``last_modified_at``,\nyou need to inherit from ``CreatedModifiedByMixin`` aswell as ``RevisionModelMixin``. For the Python MRO to work, you also\nhave to create an abstract base model:\n\n.. code-block:: python\n\n from django.db import models\n\n from django_changeset.models import CreatedModifiedByMixin, RevisionModelMixin\n from django_changeset.models.fields import ChangeSetRelation\n\n\n\n class BaseModel(models.Model):\n \"\"\"\n BaseModel is needed for proper MRO within Python/Django Models\n \"\"\"\n class Meta:\n abstract = True\n pass\n\n\n class MyModel(BaseModel, RevisionModelMixin, CreatedModifiedByMixin):\n class Meta:\n track_fields = ('my_data', ) # track changes on my_data\n track_related = ('my_ref', ) # track changes on a related model\n\n my_data = models.CharField(max_length=64, verbose_name=\"Very important data you want to track\")\n my_ref = models.ForeignKey('SomeOtherModel', verbose_name=\"Very important relation\", related_name='my_models')\n\n # Generic Relation to ChangeSet\n changesets = ChangeSetRelation()\n\n\nQuerying ChangeSets via the changesets relation\n-----------------------------------------------\n\nBy inheriting from the ``RevisionModelMixin`` and ``CreatedModifiedByMixin`` mixins, and adding an attribute of type ``ChangeSetRelation`` (a ``GenericRelation`` for the changeset), the following features are added to your model:\n\n- Properties ``created_by``, ``created_at``, ``last_modified_by``, ``last_modified_at`` are made available for each object (``CreatedModifiedByMixin``)\n- Relation ``changesets`` is made available, allowing you to run queries like this one:\n ``MyModel.objects.filter(changesets__changeset_type='I', changesets__user__username='johndoe')``\n\n\n\nAccess ChangeSets and ChangeRecords\n-----------------------------------\n\nToDo\n\nYou can access the changeset by calling the ``change_set`` property of an instance of ``MyModel`` as shown in the\nfollowing example:\n\n.. code-block:: python\n\n print(\"------- CHANGE SETS (\", len(somemodel.changesets), \")---------\")\n for change_set in somemodel.changesets:\n # print change_set\n print(\"Change was carried out at \", change_set.date, \" by user \", change_set.user, \" on model \", change_set.object_type)\n\n print(\" + CHANGE RECORDS (\", len(change_set.change_records.all()), \"): \")\n for change_record in change_set.change_records.all():\n print(\"\\t\", change_record)\n print(\"\\tIs change on a related field?\", change_record.is_related)\n # related fields: we only know that something new has been added. we know the PK, but not the object itself\n print(\"\\t\\tChanged field \", change_record.field_name, \"(\", change_record.field_verbose_name, \") from \",\n change_record.old_value, \"(display:\", change_record.old_value_display, \") to\")\n print(\"\\t\\t \", change_record.new_value, \"(display:\", change_record.new_value_display, \")\")\n if change_record.is_related:\n print(\"\\t\\tRelated Object Info: \", change_record.related_object)\n # TODO:\n # change_set.created_at, change_set.created_by, change_set.last_modified_by, change_set.last_modified_at\n\n print(\"-----\")\n\n\nMaintainers\n-----------\nThis repository is currently maintained by\n\n- beachmachine\n- ChristianKreuzberger\n\nPull Requests are welcome.\n\nLicense\n-------\n\nDjango ChangeSet uses the BSD-3 Clause License, see LICENSE file.\n\n\nChangelog / Release History\n---------------------------\n\n1.0.0rc3 - August 2018 - First feature complete release (release candidate)\n1.0.0rc4 - October 2018 - Added tracking for generic relations and improved logging (release candidate)\n", "description_content_type": "", "docs_url": null, "download_url": "", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "https://ks.co.at/", "keywords": "", "license": "BSD License", "maintainer": "", "maintainer_email": "", "name": "django-changeset", "package_url": "https://pypi.org/project/django-changeset/", "platform": "", "project_url": "https://pypi.org/project/django-changeset/", "project_urls": { "Homepage": "https://ks.co.at/" }, "release_url": "https://pypi.org/project/django-changeset/1.0rc3/", "requires_dist": null, "requires_python": "", "summary": "A simple Django app that will give your models the possibility to track all changes.", "version": "1.0rc3" }, "last_serial": 5357040, "releases": { "1.0rc1": [ { "comment_text": "", "digests": { "md5": "0e9b74c0a2b5d3f7e79d00653dbfffaf", "sha256": "12713540dd7f024e940150f59b17ef6a4e14639ac3a94c2aa6e09643bae955ea" }, "downloads": -1, "filename": "django-changeset-1.0rc1.tar.gz", "has_sig": false, "md5_digest": "0e9b74c0a2b5d3f7e79d00653dbfffaf", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17585, "upload_time": "2018-08-07T14:45:34", "url": "https://files.pythonhosted.org/packages/df/8b/6ece47821da984355bd01b3d37ce3a9f1c2e356179fa6524da4bafba7d22/django-changeset-1.0rc1.tar.gz" } ], "1.0rc2": [ { "comment_text": "", "digests": { "md5": "adec39911e33648277b6e929a25dbb45", "sha256": "4bbc50729fd7c3fcf4010820f8dc9400ac1bfee10c917c957f5db145438244cb" }, "downloads": -1, "filename": "django-changeset-1.0rc2.tar.gz", "has_sig": false, "md5_digest": "adec39911e33648277b6e929a25dbb45", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17326, "upload_time": "2018-08-10T12:48:52", "url": "https://files.pythonhosted.org/packages/f1/64/e4c66403950277cfa5d94efc49b7e44bf8e0c004b3aea8091b30aea0a5b4/django-changeset-1.0rc2.tar.gz" } ], "1.0rc3": [ { "comment_text": "", "digests": { "md5": "d8a47b3e6c9515040604de68850b27c9", "sha256": "9ceb7b4b62b915db11ca93ba1c64240637e6076c2e66abba08c3188bd4c4e6a8" }, "downloads": -1, "filename": "django-changeset-1.0rc3.tar.gz", "has_sig": false, "md5_digest": "d8a47b3e6c9515040604de68850b27c9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17397, "upload_time": "2018-10-18T11:40:18", "url": "https://files.pythonhosted.org/packages/c1/a1/49acc8d9300b833a640b0ba188f098f525771840f7eaf145cb1d998359a3/django-changeset-1.0rc3.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "d8a47b3e6c9515040604de68850b27c9", "sha256": "9ceb7b4b62b915db11ca93ba1c64240637e6076c2e66abba08c3188bd4c4e6a8" }, "downloads": -1, "filename": "django-changeset-1.0rc3.tar.gz", "has_sig": false, "md5_digest": "d8a47b3e6c9515040604de68850b27c9", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 17397, "upload_time": "2018-10-18T11:40:18", "url": "https://files.pythonhosted.org/packages/c1/a1/49acc8d9300b833a640b0ba188f098f525771840f7eaf145cb1d998359a3/django-changeset-1.0rc3.tar.gz" } ] }