pax_global_header00006660000000000000000000000064132316077500014516gustar00rootroot0000000000000052 comment=693e0dad6caa1e36edfce3dc8308fb28b2e65f44 django-reversion-2.0.13/000077500000000000000000000000001323160775000150555ustar00rootroot00000000000000django-reversion-2.0.13/.coveragerc000066400000000000000000000006321323160775000171770ustar00rootroot00000000000000[run] source = reversion test_app test_project [report] exclude_lines = # Have to re-enable the standard pragma pragma: no cover # Don't complain if tests don't hit defensive assertion code: raise AssertionError raise NotImplementedError assert False # Don't complain if tests don't hit model __str__ methods. def __str__ show_missing = True skip_covered = True django-reversion-2.0.13/.gitignore000066400000000000000000000001741323160775000170470ustar00rootroot00000000000000.DS_Store *.db .project .pydevproject .settings *.pyc *.pyo dist build MANIFEST *.egg-info/ docs/_build .coverage *.sqlite3 django-reversion-2.0.13/.travis.yml000066400000000000000000000025021323160775000171650ustar00rootroot00000000000000sudo: false language: python python: - 3.6 - 3.5 - 2.7 cache: pip env: global: - PYTHONWARNINGS=default,ignore::PendingDeprecationWarning,ignore::ResourceWarning - DJANGO_DATABASE_USER_POSTGRES=postgres - DJANGO_DATABASE_USER_MYSQL=travis matrix: - DJANGO='>=2.0,<2.1' - DJANGO='>=1.11,<1.12' - DJANGO='>=1.10,<1.11' - DJANGO='>=1.9,<1.10' - DJANGO='>=1.8,<1.9' matrix: fast_finish: true exclude: - python: 2.7 env: DJANGO='>=2.0,<2.1' addons: apt: packages: - libmysqlclient-dev services: - postgresql - mysql install: - pip install flake8 coverage mock sphinx django$DJANGO psycopg2 mysqlclient -e . before_script: - mysql -e 'create database test_project' - psql -c 'create database test_project;' -U postgres; script: - flake8 - coverage run tests/manage.py test tests - (cd docs && sphinx-build -n -W . _build) after_success: - coverage report deploy: provider: pypi user: etianen password: secure: XW4/9HiChbPJSJe4d/MRcO+ViPGhW1iQ8kVi814KJh7mCxOAKijpW5hfdc9oSKB6d8iYB3OzZ7naIUU9GMce40bpeTgPDLVBLCSYKRNLuVoJdh+Q6ItGUiFf8kAJz5jgopG80QnCpLA9JvYxKVJ4amfYWWm204eQmIEnRRAd+Jk= on: tags: true condition: $DJANGO='>=2.0,<2.1' python: 3.6 repo: etianen/django-reversion distributions: sdist bdist_wheel notifications: email: false django-reversion-2.0.13/CHANGELOG.rst000066400000000000000000000530361323160775000171050ustar00rootroot00000000000000.. _changelog: django-reversion changelog ========================== 2.0.13 - 23/01/2017 ------------------- - Improve performance of ``get_deleted()`` for Oracle (@passuf). - Minor tweaks (@etianen, @michael-k). 2.0.12 - 05/12/2017 ------------------- - Fixed MySQL error in ``get_deleted()``. 2.0.11 - 27/11/2017 ------------------- - Dramatically improved performance of ``get_deleted()`` over large datasets (@alexey-v-paramonov, @etianen). - Ukranian translation (@illia-v). - Bugfixes (@achidlow, @claudep, @etianen). 2.0.10 - 18/08/2017 ------------------- - Bugfix: Handling case of `None` user in request (@pawelad). - Documentation corrections (@danielquinn). - Bugfix: "invalid literal for int() with base 10: 'None'" for unversioned admin inline relations. If, after updating, you still experience this issue, run the following in a Django shell: .. code:: from reversion.models import Version Version.objects.filter(object_id="None").delete() **Important:** Ensure that none of your versioned models contain a string primary key where `"None"` is a valid value before running this snippet! 2.0.9 - 19/06/2017 ------------------ - Bugfix: Deleted inline admin instances no longer added to revision. - Bugfix: M2M relations correctly added to revision (@etianen, @claudep). - Improved performance of 0003 migration (@mkurek). - Documentation improvements (@orlra, @guettli, @meilinger). - Django 1.11 support (@claudep). - Added ``atomic=True`` parameter to ``create_revision`` (Ernesto Ferro). 2.0.8 - 28/11/2016 ------------------ - Setting ``revision.user`` in ``process_response`` for middleware (@etianen). - Fixing localization of model primary keys in `recover_list.html` (@w4rri0r3k). - Documentation tweaks (@jaywink). 2.0.7 - 31/10/2016 ------------------ - Database migrations now db-aware (@alukach). - Added "revert" and "recover" context variables to admin templates (@kezabelle). - Added ``post_revision_commit`` and ``pre_revision_commit`` signals back in (@carlosxl). - Fixing datetime in admin change message (@arogachev). - Fixing performance bug in postgres (@st4lk). - Fixing admin change messages in Django 1.10+ (@claudep). - Fixing revision middleware behavior in Django 1.10+ (@etianen). - Documentation tweaks (@jschneier). - Deprecation fixes (@KhasanovBI, @zsiciarz, @claudep). - Releasing as a universal wheel (@adamchainz). 2.0.6 - 21/07/2016 ------------------ - Fixed ``RevisionMiddleware`` always rolling back transactions in gunicorn (@stebunovd, @etianen). - Tweaks and minor bugfixes (@SahilMak). 2.0.5 - 29/06/2016 ------------------ - Fixed LookupError when running migration 0003 with stale content types (@etianen). 2.0.4 - 20/06/2016 ------------------ - Fixed LookupError when running migration 0003 (@etianen). - Fixed duplicate versions using ``get_deleted()`` (@etianen). - Fixed unexpected deletion of underflowing revisions when using ``--keep`` switch with ``deleterevisions`` (@etianen). 2.0.3 - 14/06/2016 ------------------ - Added support for m2m fields with a custom ``through`` model (@etianen). 2.0.2 - 13/06/2016 ------------------ - Fixing migration 0003 in MySQL (@etianen). 2.0.1 - 13/06/2016 ------------------ - Improved performance of migration 0003 (@BertrandBordage). - De-duplicating ``Version`` table before applying migration 0004 (@BertrandBordage, @etianen). 2.0.0 - 11/06/2016 ------------------ django-reversion was first released in May 2008, and has been in active development ever since. Over this time it's developed a certain amount of cruft from legacy and unused features, resulting in needless complexity and multiple ways of achieving the same task. This release substantially cleans and refactors the codebase. Much of the top-level functionality remains unchanged or is very similar. The release notes are divided into subsections to make it easier to find out where you need to update your code. This release includes a migration for the ``Version`` model that may take some time to complete. General improvements ^^^^^^^^^^^^^^^^^^^^ * Dramatically improved performance of version lookup for models with a non-integer primary key (@etianen, @mshannon1123). * Documentation refactor (@etianen). * Test refactor (@etianen). * Minor tweaks and bugfixes (@etianen, @bmarika, @ticosax). Admin ^^^^^ * Fixed issue with empty revisions being created in combination with ``RevisionMiddleware`` (@etianen). * **Breaking:** Removed ``reversion_format`` property from ``VersionAdmin`` (@etianen). Use ``VersionAdmin.reversion_register`` instead. .. code:: class YourVersionAdmin(VersionAdmin): def reversion_register(self, model, **options): options["format"] = "yaml" super(YourVersionAdmin, self).reversion_register(model, **options) * **Breaking:** Removed ``ignore_duplicate_revisions`` property from ``VersionAdmin`` (@etianen). Use ``VersionAdmin.reversion_register`` instead. .. code:: class YourVersionAdmin(VersionAdmin): def reversion_register(self, model, **options): options["ignore_duplicate_revisions"] = True super(YourVersionAdmin, self).reversion_register(model, **options) Management commands ^^^^^^^^^^^^^^^^^^^ * **Breaking:** Refactored arguments to ``createinitialrevisions`` (@etianen). All existing functionality should still be supported, but several parameter names have been updated to match Django coding conventions. Check the command ``--help`` for details. * **Breaking:** Refactored arguments to ``deleterevisions`` (@etianen). All existing functionality should still be supported, but several parameter names have been updated to match Django coding conventions, and some duplicate parameters have been removed. The confirmation prompt has been removed entirely, and the command now always runs in the ``--force`` mode from the previous version. Check the command ``--help`` for details. Middleware ^^^^^^^^^^ * Added support for using ``RevisionMiddleware`` with new-style Django 1.10 ``MIDDLEWARE`` (@etianen). * Middleware wraps entire request in ``transaction.atomic()`` to preserve transactional integrity of revision and models (@etianen). View helpers ^^^^^^^^^^^^ * Added ``reversion.views.create_revision`` view decorator (@etianen). * Added ``reversion.views.RevisionMixin`` class-based view mixin (@etianen). Low-level API ^^^^^^^^^^^^^ * Restored many of the django-reversion API methods back to the top-level namespace (@etianen). * Revision blocks are now automatically wrapped in ``transaction.atomic()`` (@etianen). * Added ``for_concrete_model`` argument to ``reversion.register()`` (@etianen). * Added ``Version.objects.get_for_model()`` lookup function (@etianen). * Added ``reversion.add_to_revision()`` for manually adding model instances to an active revision (@etianen). * Removed ``Version.object_id_int`` field, in favor of a unified ``Version.object_id`` field for all primary key types (@etianen). * **Breaking:** ``reversion.get_for_object_reference()`` has been moved to ``Version.objects.get_for_object_reference()`` (@etianen). * **Breaking:** ``reversion.get_for_object()`` has been moved to ``Version.objects.get_for_object()`` (@etianen). * **Breaking:** ``reversion.get_deleted()`` has been moved to ``Version.objects.get_deleted()`` (@etianen). * **Breaking:** ``Version.object_version`` has been renamed to ``Version._object_version`` (@etianen). * **Breaking:** Refactored multi-db support (@etianen). django-reversion now supports restoring model instances to their original database automatically. Several parameter names have also be updated to match Django coding conventions. If you made use of the previous multi-db functionality, check the latest docs for details. Otherwise, everything should *just work*. * **Breaking:** Removed ``get_ignore_duplicates`` and ``set_ignore_duplicates`` (@etianen). ``ignore_duplicates`` is now set in reversion.register() on a per-model basis. * **Breaking:** Removed ``get_for_date()`` function (@etianen). Use ``get_for_object().filter(revision__date_created__lte=date)`` instead. * **Breaking:** Removed ``get_unique_for_object()`` function (@etianen). Use ``get_for_object().get_unique()`` instead. * **Breaking:** Removed ``signal`` and ``eager_signals`` argument from ``reversion.register()`` (@etianen). To create revisions on signals other than ``post_save`` and ``m2m_changed``, call ``reversion.add_to_revision()`` in a signal handler for the appropriate signal. .. code:: python from django.dispatch import receiver import reversion from your_app import your_custom_signal @reciever(your_custom_signal) def your_custom_signal_handler(instance, **kwargs): if reversion.is_active(): reversion.add_to_revision(instance) This approach will work for both eager and non-eager signals. * **Breaking:** Removed ``adapter_cls`` argument from ``reversion.register()`` (@etianen). * **Breaking:** Removed ``reversion.save_revision()`` (@etianen). Use reversion.add_to_revision() instead. .. code:: python import reversion with reversion.create_revision(): reversion.add_to_revision(your_obj) Signals ^^^^^^^ * **Breaking:** Removed ``pre_revision_commit`` signal (@etianen). Use the Django standard ``pre_save`` signal for ``Revision`` instead. * **Breaking:** Removed ``post_revision_commit`` signal (@etianen). Use the Django standard ``post_save`` signal for ``Revision`` instead. Helpers ^^^^^^^ * **Breaking:** Removed ``patch_admin`` function (@etianen). Use ``VersionAdmin`` as a mixin to 3rd party ModelAdmins instead. .. code:: @admin.register(SomeModel) class YourModelAdmin(VersionAdmin, SomeModelAdmin): pass * **Breaking:** Removed ``generate_diffs`` function (@etianen). django-reversion no supports an official diff helper. There are much better ways of achieving this now, such as `django-reversion-compare `_. The old implementation is available for reference from the `previous release `_. * **Breaking:** Removed ``generate_patch`` function (@etianen). django-reversion no supports an official diff helper. There are much better ways of achieving this now, such as `django-reversion-compare `_. The old implementation is available for reference from the `previous release `_. * **Breaking:** Removed ``generate_patch_html`` function (@etianen). django-reversion no supports an official diff helper. There are much better ways of achieving this now, such as `django-reversion-compare `_. The old implementation is available for reference from the `previous release `_. Models ^^^^^^ * **Breaking:** Ordering of ``-pk`` added to models ``Revision`` and ``Version``. Previous was the default ``pk``. 1.10.2 - 18/04/2016 ------------------- * Fixing deprecation warnings (@claudep). * Minor tweaks and bug fixes (@fladi, @claudep, @etianen). 1.10.1 - 27/01/2016 ------------------- * Fixing some deprecation warnings (@ticosax). * Minor tweaks (@claudep, @etianen). 1.10 - 02/12/2015 ----------------- * **Breaking:** Updated the location of ``VersionAdmin``. Prior to this change, you could access the ``VersionAdmin`` class using the following import: .. code:: python # Old-style import for accessing the admin class. import reversion # Access admin class from the reversion namespace. class YourModelAdmin(reversion.VersionAdmin): pass In order to support Django 1.9, the admin class has been moved to the following import: .. code:: python # New-style import for accesssing admin class. from reversion.admin import VersionAdmin # Use the admin class directly. class YourModelAdmin(VersionAdmin): pass * **Breaking:** Updated the location of low-level API methods. Prior to this change, you could access the low-level API using the following import: .. code:: python # Old-style import for accessing the low-level API. import reversion # Use low-level API methods from the reversion namespace. @reversion.register class YourModel(models.Model): pass In order to support Django 1.9, the low-level API methods have been moved to the following import: .. code:: python # New-style import for accesssing the low-level API. from reversion import revisions as reversion # Use low-level API methods from the revisions namespace. @reversion.register class YourModel(models.Model): pass * **Breaking:** Updated the location of http://django-reversion.readthedocs.org/en/latest/signals.html. Prior to this change, you could access the reversion signals using the following import: .. code:: python # Old-style import for accessing the reversion signals import reversion # Use signals from the reversion namespace. reversion.post_revision_commit.connect(...) In order to support Django 1.9, the reversion signals have been moved to the following import: .. code:: python # New-style import for accesssing the reversion signals. from reversion.signals import pre_revision_commit, post_revision_commit # Use reversion signals directly. post_revision_commit.connect(...) * Django 1.9 compatibility (@etianen). * Added spanish (argentina) translation (@gonzalobustos). * Minor bugfixes and tweaks (@Blitzstok, @IanLee1521, @lutoma, @siamalekpour, @etianen). 1.9.3 - 07/08/2015 ------------------ * Fixing regression with admin redirects following save action (@etianen). 1.9.2 - 07/08/2015 ------------------ * Fixing regression with "delete", "save as new" and "save and continue" button being shown in recover and revision admin views (@etianen). * Fixing regression where VersionAdmin.ignore_duplicate_revisions was ignored (@etianen). 1.9.1 - 04/08/2015 ------------------ * Fixing packaging error that rendered the 1.9.0 release unusable. No way to cover up the mistake, so here's a brand new bugfix release! (@etianen). 1.9.0 - 04/08/2015 ------------------ * Using database transactions do render consistent views of past revisions in database admin, fixing a lot of lingering minor issues (@etianen). * Correct handling of readonly fields in admin (@etianen). * Updates to Czech translation (@cuchac). * Arabic translation (@RamezIssac). * Fixing deleterevisions to work with Python2 (@jmurty). * Fixing edge-cases where an object does not have a PK (@johnfraney). * Tweaks, code cleanups and documentation fixes (@claudep, @johnfraney, @podloucky-init, Drew Hubl, @JanMalte, @jmurty, @etianen). 1.8.7 - 21/05/2015 ------------------ * Fixing deleterevisions command on Python 3 (@davidfsmith). * Fixing Django 1.6 compatibility (@etianen). * Removing some Django 1.9 deprecation warnings (@BATCOH, @niknokseyer). * Minor tweaks (@nikolas, @etianen). 1.8.6 - 13/04/2015 ------------------ * Support for MySQL utf8mb4 (@alexhayes). * Fixing some Django deprecation warnings (Drew Hubl, @khakulov, @adonm). * Versions passed through by reversion.post_revision_commit now contain a primary key (@joelarson). 1.8.5 - 31/10/2014 ------------------ * Added support for proxy models (@AgDude, @bourivouh). * Allowing registration of models with django-reversion using custom signals (@ErwinJunge). * Fixing some Django deprecation warnings (@skipp, @narrowfail). 1.8.4 - 07/09/2014 ------------------ * Fixing including legacy south migrations in PyPi package (@GeyseR). 1.8.3 - 06/09/2014 ------------------ * Provisional Django 1.7 support (@etianen). * Multi-db and multi-manager support to management commands (@marekmalek). * Added index on reversion.date_created (@rkojedzinszky). * Minor bugfixes and documentation improvements (@coagulant). 1.8.2 - 01/08/2014 ------------------ * reversion.register() can now be used as a class decorator (@aquavitae). * Danish translation (@Vandborg). * Improvements to Travis CI integration (@thedrow). * Simplified Chinese translation (@QuantumGhost). * Minor bugfixes and documentation improvements (@marekmalek, @dhoffman34, @mauricioabreu, @mark0978). 1.8.1 - 29/05/2014 ------------------ * Slovak translation (@jbub). * Deleting a user no longer deletes the associated revisions (@daaray). * Improving handling of inline models in admin integration (@blueyed). * Improving error messages for proxy model registration (@blueyed). * Improvements to using migrations with custom user model (@aivins). * Removing sys.exit() in deleterevisions management command, allowing it to be used internally by Django projects (@tongwang). * Fixing some backwards-compatible admin deprecation warnings (Thomas Schreiber). * Fixing tests if RevisionMiddleware is used as a decorator in the parent project (@jmoldow). * Derived models, such as those generated by deferred querysets, now work. * Removed deprecated low-level API methods. 1.8.0 - 01/11/2013 ------------------ * Django 1.6 compatibility (@niwibe & @meshy). * Removing type flag from Version model. * Using bulk_create to speed up revision creation. * Including docs in source distribution (@pquentin & @fladi). * Spanish translation (@alexander-ae). * Fixing edge-case bugs in revision middleware (@pricem & @oppianmatt). 1.7.1 - 26/06/2013 ------------------ * Bugfixes when using a custom User model. * Minor bugfixes. 1.7 - 27/02/2013 ---------------- * Django 1.5 compatibility. * Experimantal Python 3.3 compatibility! 1.6.6 - 12/02/2013 ------------------ * Removing version checking code. It's more trouble than it's worth. * Dutch translation improvements. 1.6.5 - 12/12/2012 ------------------ * Support for Django 1.4.3. 1.6.4 - 28/10/2012 ------------------ * Support for Django 1.4.2. 1.6.3 - 05/09/2012 ------------------ * Fixing issue with reverting models with unique constraints in the admin. * Enforcing permissions in admin views. 1.6.2 - 31/07/2012 ------------------ * Batch saving option in createinitialrevisions. * Suppressing warning for Django 1.4.1. 1.6.1 - 20/06/2012 ------------------ * Swedish translation. * Fixing formating for PyPi readme and license. * Minor features and bugfixes. 1.6 - 27/03/2012 ---------------- * Django 1.4 compatibility. 1.5.2 - 27/03/2012 ------------------ * Multi-db support. * Brazillian Portuguese translation. * New manage_manually revision mode. 1.5.1 - 20/10/2011 ------------------- * Polish translation. * Minor bug fixes. 1.5 - 04/09/2011 ---------------- * Added in simplified low level API methods, and deprecated old low level API methods. * Added in support for multiple revision managers running in the same project. * Added in significant speedups for models with integer primary keys. * Added in cleanup improvements to patch generation helpers. * Minor bug fixes. 1.4 - 27/04/2011 ---------------- * Added in a version flag for add / change / delete annotations. * Added experimental deleterevisions management command. * Added a --comment option to createinitialrevisions management command. * Django 1.3 compatibility. 1.3.3 - 05/03/2011 ------------------ * Improved resilience of revert() to database integrity errors. * Added in Czech translation. * Added ability to only save revisions if there is no change. * Fixed long-running bug with file fields in inline related admin models. * Easier debugging for createinitialrevisions command. * Improved compatibility with Oracle database backend. * Fixed error in MySQL tests. * Greatly improved performance of get_deleted() Version manager method. * Fixed an edge-case UnicodeError. 1.3.2 - 22/10/2010 ------------------ * Added Polish translation. * Added French translation. * Improved resilience of unit tests. * Improved scaleability of Version.object.get_deleted() method. * Improved scaleability of createinitialrevisions command. * Removed post_syncdb hook. * Added new createinitialrevisions management command. * Fixed DoesNotExistError with OneToOneFields and follow. 1.3.1 - 31/05/2010 ------------------ This release is compatible with Django 1.2.1. * Django 1.2.1 admin compatibility. 1.2.1 - 03/03/2010 ------------------ This release is compatible with Django 1.1.1. * The django syncdb command will now automatically populate any version-controlled models with an initial revision. This ensures existing projects that integrate Reversion won't get caught out. * Reversion now works with SQLite for tables over 999 rows. * Added Hebrew translation. 1.2 - 12/10/2009 ---------------- This release is compatible with Django 1.1. * Django 1.1 admin compatibility. 1.1.2 - 23/07/2009 ------------------ This release is compatible with Django 1.0.4. * Doc tests. * German translation update. * Better compatibility with the Django trunk. * The ability to specify a serialization format used by the ReversionAdmin class when models are auto-registered. * Reduction in the number of database queries performed by the Reversion * admin interface. 1.1.1 - 25/03/2010 ------------------ This release is compatible with Django 1.0.2. * German and Italian translations. * Helper functions for generating diffs. * Improved handling of one-to-many relationships in the admin. django-reversion-2.0.13/LICENSE000066400000000000000000000027641323160775000160730ustar00rootroot00000000000000Copyright (c) 2009, David Hall. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 3. Neither the name of David Hall nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. django-reversion-2.0.13/MANIFEST.in000066400000000000000000000003621323160775000166140ustar00rootroot00000000000000include reversion/templates/reversion/*.html include reversion/locale/*/LC_MESSAGES/django.* include LICENSE include README.rst include CHANGELOG.rst include MANIFEST.in recursive-include docs * recursive-include tests *.py prune docs/_build django-reversion-2.0.13/README.rst000066400000000000000000000035171323160775000165520ustar00rootroot00000000000000django-reversion ================ **django-reversion** is an extension to the Django web framework that provides version control for model instances. Features -------- - Roll back to any point in a model instance's history. - Recover deleted model instances. - Simple admin integration. Documentation ------------- Please read the `Getting Started `_ guide for more information. Issue tracking and source code can be found at the `main project website `_. You can keep up to date with the latest announcements by joining the `django-reversion discussion group `_. Upgrading --------- Please check the `Changelog `_ before upgrading your installation of django-reversion. Contributing ------------ Bug reports, bug fixes, and new features are always welcome. Please raise issues on the `django-reversion project site `_, and submit pull requests for any new code. You can run the test suite yourself from within a virtual environment with the following commands. The test suite requires that both MySQL and PostgreSQL be installed. .. code:: bash pip install psycopg2 mysqlclient -e . tests/manage.py test tests The django-reversion project is built on every push with `Travis CI `_. .. image:: https://travis-ci.org/etianen/django-reversion.svg?branch=master :target: https://travis-ci.org/etianen/django-reversion Contributors ------------ The django-reversion project was developed by `Dave Hall `_ and contributed to by `many other people `_. django-reversion-2.0.13/docs/000077500000000000000000000000001323160775000160055ustar00rootroot00000000000000django-reversion-2.0.13/docs/_include/000077500000000000000000000000001323160775000175675ustar00rootroot00000000000000django-reversion-2.0.13/docs/_include/admin.rst000066400000000000000000000004421323160775000214110ustar00rootroot00000000000000Register your models with a subclass of :ref:`VersionAdmin`. .. code:: python from django.contrib import admin from reversion.admin import VersionAdmin @admin.register(YourModel) class YourModelAdmin(VersionAdmin): pass .. include:: /_include/post-register.rst django-reversion-2.0.13/docs/_include/create-revision-args.rst000066400000000000000000000003251323160775000243520ustar00rootroot00000000000000``manage_manually`` .. include:: /_include/create-revision-manage-manually.rst ``using`` .. include:: /_include/create-revision-using.rst ``atomic`` .. include:: /_include/create-revision-atomic.rst django-reversion-2.0.13/docs/_include/create-revision-atomic.rst000066400000000000000000000001171323160775000246710ustar00rootroot00000000000000If ``True``, the revision block will be wrapped in a ``transaction.atomic()``. django-reversion-2.0.13/docs/_include/create-revision-manage-manually.rst000066400000000000000000000002371323160775000264700ustar00rootroot00000000000000If ``True``, versions will not be saved when a model's ``save()`` method is called. This allows version control to be switched off for a given revision block. django-reversion-2.0.13/docs/_include/create-revision-using.rst000066400000000000000000000002651323160775000245460ustar00rootroot00000000000000The database to save the revision data. The revision block will be wrapped in a transaction using this database. If ``None``, the default database for :ref:`Revision` will be used. django-reversion-2.0.13/docs/_include/model-db-arg.rst000066400000000000000000000001501323160775000225470ustar00rootroot00000000000000``model_db`` The database where the model is saved. Defaults to the default database for the model. django-reversion-2.0.13/docs/_include/post-register.rst000066400000000000000000000001461323160775000231310ustar00rootroot00000000000000.. Hint:: Whenever you register a model with django-reversion, run :ref:`createinitialrevisions`. django-reversion-2.0.13/docs/_include/signal-args.rst000066400000000000000000000002431323160775000225270ustar00rootroot00000000000000``sender`` The ``reversion.create_revision`` object. ``revision`` The :ref:`Revision` model. ``versions`` The :ref:`Version` models in the revision. django-reversion-2.0.13/docs/_include/throws-registration-error.rst000066400000000000000000000001341323160775000255040ustar00rootroot00000000000000Throws :ref:`RegistrationError` if the model has not been registered with django-reversion. django-reversion-2.0.13/docs/_include/throws-revert-error.rst000066400000000000000000000002331323160775000243010ustar00rootroot00000000000000Throws :ref:`RevertError` if the model could not be deserialized or reverted, e.g. the serialized data is not compatible with the current database schema. django-reversion-2.0.13/docs/_include/throws-revision-error.rst000066400000000000000000000001141323160775000246260ustar00rootroot00000000000000Throws :ref:`RevisionManagementError` if there is no active revision block. django-reversion-2.0.13/docs/admin.rst000066400000000000000000000062041323160775000176310ustar00rootroot00000000000000.. _admin: Admin integration ================= django-reversion can be used to add rollback and recovery to your admin site. .. Warning:: The admin integration requires that your database engine supports transactions. This is the case for PostgreSQL, SQLite and MySQL InnoDB. If you are using MySQL MyISAM, upgrade your database tables to InnoDB! Overview -------- Registering models ^^^^^^^^^^^^^^^^^^ .. include:: /_include/admin.rst .. Note:: If you've registered your models using :ref:`reversion.register() `, the admin class will use the configuration you specify there. Otherwise, the admin class will auto-register your model, following all inline model relations and parent superclasses. Customize the admin registration by overriding :ref:`VersionAdmin.register() `. Integration with 3rd party apps ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ You can use :ref:`VersionAdmin` as a mixin with a 3rd party admin class. .. code:: python @admin.register(SomeModel) class YourModelAdmin(VersionAdmin, SomeModelAdmin): pass If the 3rd party model is already registered with the Django admin, you may have to unregister it first. .. code:: python admin.site.unregister(SomeModel) @admin.register(SomeModel) class YourModelAdmin(VersionAdmin, SomeModelAdmin): pass .. _VersionAdmin: reversion.admin.VersionAdmin ---------------------------- A subclass of ``django.contrib.ModelAdmin`` providing rollback and recovery. ``revision_form_template = None`` A custom template to render the revision form. Alternatively, create specially named templates to override the default templates on a per-model or per-app basis. * ``'reversion/app_label/model_name/revision_form.html'`` * ``'reversion/app_label/revision_form.html'`` * ``'reversion/revision_form.html'`` ``recover_list_template = None`` A custom template to render the recover list. Alternatively, create specially named templates to override the default templates on a per-model or per-app basis. * ``'reversion/app_label/model_name/recover_list.html'`` * ``'reversion/app_label/recover_list.html'`` * ``'reversion/recover_list.html'`` ``recover_form_template = None`` A custom template to render the recover form. * ``'reversion/app_label/model_name/recover_form.html'`` * ``'reversion/app_label/recover_form.html'`` * ``'reversion/recover_form.html'`` ``history_latest_first = False`` If ``True``, revisions will be displayed with the most recent revision first. .. _VersionAdmin_register: ``reversion_register(model, **options)`` Callback used by the auto-registration machinery to register the model with django-reversion. Override this to customize how models are registered. .. code:: python def reversion_register(self, model, **options): options["exclude"] = ("some_field",) super(YourModelAdmin, self).reversion_register(model, **options) ``model`` The model that will be registered with django-reversion. ``options`` Registeration options, see :ref:`reversion.register() `. django-reversion-2.0.13/docs/api.rst000066400000000000000000000303061323160775000173120ustar00rootroot00000000000000.. _api: django-reversion API ==================== Use the django-reversion API to build version-controlled apps. See also :ref:`Views` and :ref:`Middleware`. Overview -------- Registering models ^^^^^^^^^^^^^^^^^^ Models must be registered with django-reversion before they can be used with the API. .. code:: python from django.db import models import reversion @reversion.register() class YourModel(models.Model): pass .. Hint:: If you're using the :ref:`admin`, model registration is automatic. If you’re using django-reversion in a management command, make sure you call ``django.contrib.admin.autodiscover()`` to load the admin modules before using the django-reversion API. .. include:: /_include/post-register.rst Creating revisions ^^^^^^^^^^^^^^^^^^ A *revision* represents one or more changes made to your model instances, grouped together as a single unit. You create a revision by creating a *revision block*. When you call ``save()`` on a registered model inside a revision block, it will be added to that revision. .. code:: python # Declare a revision block. with reversion.create_revision(): # Save a new model instance. obj = YourModel() obj.name = "obj v1" obj.save() # Store some meta-information. reversion.set_user(request.user) reversion.set_comment("Created revision 1") # Declare a new revision block. with reversion.create_revision(): # Update the model instance. obj.name = "obj v2" obj.save() # Store some meta-information. reversion.set_user(request.user) reversion.set_comment("Created revision 2") .. Important:: Bulk actions, such as ``Queryset.update()``, do not send signals, so won't be noticed by django-reversion. Loading revisions ^^^^^^^^^^^^^^^^^ Each model instance saved in a revision block is serialized as a :ref:`Version`. All versions in a revision block are associated with a single :ref:`Revision`. You can load a :ref:`VersionQuerySet` of versions from the database. Versions are loaded with the most recent version first. .. code:: python from reversion.models import Version # Load a queryset of versions for a specific model instance. versions = Version.objects.get_for_object(instance) assert len(versions) == 2 # Check the serialized data for the first version. assert versions[1].field_dict["name"] = "obj v1" # Check the serialized data for the second version. assert versions[0].field_dict["name"] = "obj v2" Revision metadata ^^^^^^^^^^^^^^^^^ :ref:`Revision` stores meta-information about the revision. .. code:: python # Check the revision metadata for the first revision. assert versions[1].revision.comment = "Created revision 1" assert versions[1].revision.user = request.user assert isinstance(versions[1].revision.date_created, datetime.datetime) # Check the revision metadata for the second revision. assert versions[0].revision.comment = "Created revision 2" assert versions[0].revision.user = request.user assert isinstance(versions[0].revision.date_created, datetime.datetime) Reverting revisions ^^^^^^^^^^^^^^^^^^^ Revert a :ref:`Revision` to restore the serialized model instances. .. code:: python # Revert the first revision. versions[1].revision.revert() # Check the model instance has been reverted. obj.refresh_from_db() assert obj.name == "version 1" # Revert the second revision. versions[0].revision.revert() # Check the model instance has been reverted. obj.refresh_from_db() assert obj.name == "version 2" Restoring deleted model instances ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Reverting a :ref:`Revision` will restore any serialized model instances that have been deleted. .. code:: python # Delete the model instance, but store the pk. pk = obj.pk obj.delete() # Revert the second revision. versions[0].revision.revert() # Check the model has been restored to the database. obj = YourModel.objects.get(pk=obj.pk) assert obj.name == "version 2" .. _registration-api: Registration API ---------------- .. _register: ``reversion.register(model, **options)`` Registers a model with django-reversion. Throws :ref:`RegistrationError` if the model has already been registered. ``model`` The Django model to register. ``fields=None`` An iterable of field names to include in the serialized data. If ``None``, all fields will be included. ``exclude=()`` An iterable of field names to exclude from the serialized data. ``follow=()`` An iterable of model relationships to follow when saving a version of this model. ``ForeignKey``, ``ManyToManyField`` and reversion ``ForeignKey`` relationships are supported. Any property that returns a ``Model`` or ``QuerySet`` is also supported. ``format="json"`` The name of a Django serialization format to use when saving the model instance. ``for_concrete_model=True`` If ``True`` proxy models will be saved under the same content type as their concrete model. If ``False``, proxy models will be saved under their own content type, effectively giving proxy models their own distinct history. ``ignore_duplicates=False`` If ``True``, then an additional check is performed to avoid saving duplicate versions for this model. Checking for duplicate revisions adds significant overhead to the process of creating a revision. Don't enable it unless you really need it! .. Hint:: By default, django-reversion will not register any parent classes of a model that uses multi-table inheritance. If you wish to also add parent models to your revision, you must explicitly add their ``parent_ptr`` fields to the ``follow`` parameter when you register the model. .. include:: /_include/post-register.rst ``reversion.is_registered(model)`` Returns whether the given model has been registered with django-reversion. ``model`` The Django model to check. ``reversion.unregister(model)`` Unregisters the given model from django-reversion. .. include:: /_include/throws-registration-error.rst ``model`` The Django model to unregister. ``reversion.get_registered_models()`` Returns an iterable of all registered models. .. _revision-api: Revision API ------------ ``reversion.create_revision(manage_manually=False, using=None, atomic=True)`` Marks a block of code as a *revision block*. Can also be used as a decorator. .. include:: /_include/create-revision-args.rst ``reversion.is_active()`` Returns whether there is currently an active revision block. ``reversion.is_manage_manually()`` Returns whether the current revision block is in ``manage_manually`` mode. ``reversion.set_user(user)`` Sets the user for the current revision. .. include:: /_include/throws-revision-error.rst ``user`` A ``User`` model instance (or whatever your ``settings.AUTH_USER_MODEL`` is). ``reversion.get_user()`` Returns the user for the current revision. .. include:: /_include/throws-revision-error.rst .. _set_comment: ``reversion.set_comment(comment)`` Sets the comment for the current revision. .. include:: /_include/throws-revision-error.rst ``comment`` The text comment for the revision. ``reversion.get_comment()`` Returns the comment for the current revision. .. include:: /_include/throws-revision-error.rst ``reversion.set_date_created(date_created)`` Sets the creation date for the current revision. .. include:: /_include/throws-revision-error.rst ``date_created`` The creation date for the revision. ``reversion.get_date_created()`` Returns the creation date for the current revision. .. include:: /_include/throws-revision-error.rst ``reversion.add_meta(model, **values)`` Adds custom metadata to a revision. .. include:: /_include/throws-revision-error.rst ``model`` A Django model to store the custom metadata. The model must have a ``ForeignKey`` or ``OneToOneField`` to :ref:`Revision`. ``**values`` Values to be stored on ``model`` when it is saved. ``reversion.add_to_revision(obj, model_db=None)`` Adds a model instance to a revision. .. include:: /_include/throws-revision-error.rst ``obj`` A model instance to add to the revision. .. include:: /_include/model-db-arg.rst .. _VersionQuerySet: reversion.models.VersionQuerySet -------------------------------- A ``QuerySet`` of :ref:`Version`. The results are ordered with the most recent :ref:`Version` first. ``Version.objects.get_for_model(model, model_db=None)`` Returns a :ref:`VersionQuerySet` for the given model. .. include:: /_include/throws-registration-error.rst ``model`` A registered model. .. include:: /_include/model-db-arg.rst ``Version.objects.get_for_object(obj, model_db=None)`` Returns a :ref:`VersionQuerySet` for the given model instance. .. include:: /_include/throws-registration-error.rst ``obj`` An instance of a registered model. .. include:: /_include/model-db-arg.rst ``Version.objects.get_for_object_reference(model, pk, model_db=None)`` Returns a :ref:`VersionQuerySet` for the given model and primary key. .. include:: /_include/throws-registration-error.rst ``model`` A registered model. ``pk`` The database primary key of a model instance. .. include:: /_include/model-db-arg.rst ``Version.objects.get_deleted(model, model_db=None)`` Returns a :ref:`VersionQuerySet` for the given model containing versions where the serialized model no longer exists in the database. .. include:: /_include/throws-registration-error.rst ``model`` A registered model. ``db`` The database to load the versions from. .. include:: /_include/model-db-arg.rst ``Version.objects.get_unique()`` Returns an iterable of :ref:`Version`, where each version is unique for a given database, model instance, and set of serialized fields. .. _Version: reversion.models.Version ------------------------ Represents a single model instance serialized in a revision. ``Version.id`` The database primary key of the :ref:`Version`. ``Version.revision`` A ``ForeignKey`` to a :ref:`Revision` instance. ``Version.content_type`` The ``ContentType`` of the serialized model instance. ``Version.object_id`` The string representation of the serialized model instance's primary key. ``Version.db`` The Django database alias where the serialized model was saved. ``Version.format`` The name of the Django serialization format used to serialize the model instance. ``Version.serialized_data`` The raw serialized data of the model instance. ``Version.object_repr`` The stored snapshot of the model instance's ``__str__`` method when the instance was serialized. ``Version.field_dict`` A dictionary of stored model fields. This includes fields from any parent models in the same revision. .. include:: /_include/throws-revert-error.rst ``Version.revert()`` Restores the serialized model instance to the database. To restore the entire revision, use :ref:`Revision.revert() `. .. include:: /_include/throws-revert-error.rst .. _Revision: reversion.models.Revision ------------------------- Contains metadata about a revision, and groups together all :ref:`Version` instances created in that revision. ``Revision.id`` The database primary key of the :ref:`Revision`. ``Revision.date_created`` A ``datetime`` when the revision was created. ``Revision.user`` The ``User`` that created the revision, or None. ``Revision.comment`` A text comment on the revision. .. _Revision-revert: ``Revision.revert(delete=False)`` Restores all contained serialized model instances to the database. .. include:: /_include/throws-revert-error.rst ``delete`` If ``True``, any model instances which have been created and are reachable by the ``follow`` clause of any model instances in this revision will be deleted. This effectively restores a group of related models to the state they were in when the revision was created. django-reversion-2.0.13/docs/changelog.rst000066400000000000000000000000361323160775000204650ustar00rootroot00000000000000.. include:: ../CHANGELOG.rst django-reversion-2.0.13/docs/commands.rst000066400000000000000000000026401323160775000203420ustar00rootroot00000000000000.. _commands: Management commands =================== django-reversion includes a number of ``django-admin.py`` management commands. .. _createinitialrevisions: createinitialrevisions ---------------------- Creates an initial revision for all registered models in your project. It should be run after installing django-reversion, or registering a new model with django-reversion. .. code:: bash ./manage.py createinitialrevisions ./manage.py createinitialrevisions your_app.YourModel --comment="Initial revision." Run ``./manage.py createinitialrevisions --help`` for more information. .. Warning:: For large databases, this command can take a long time to run. deleterevisions --------------- Deletes old revisions. It can be run regularly to keep revision history manageable. .. code:: bash ./manage.py deleterevisions # keep any changes from last 30 days ./manage.py deleterevisions your_app.YourModel --days=30 # keep 30 most recent changes for each item. ./manage.py deleterevisions your_app.YourModel --keep=30 # Keep anything from last 30 days and at least 3 from older changes. ./manage.py deleterevisions your_app.YourModel --keep=3 --days=30 Run ``./manage.py deleterevisions --help`` for more information. .. Warning:: With no arguments, this command will delete your entire revision history! Read the command help for ways to limit which revisions should be deleted. django-reversion-2.0.13/docs/common-problems.rst000066400000000000000000000010041323160775000216430ustar00rootroot00000000000000.. _common-problems: Common problems =============== RegistrationError: class 'myapp.MyModel' has already been registered with Reversion ----------------------------------------------------------------------------------- This is caused by your ``models.py`` file being imported twice, resulting in ``reversion.register()`` being called twice for the same model. This problem is almost certainly due to relative import statements in your codebase. Try converting all your relative imports into absolute imports. django-reversion-2.0.13/docs/conf.py000066400000000000000000000230371323160775000173110ustar00rootroot00000000000000#!/usr/bin/env python3 # -*- coding: utf-8 -*- # # django-reversion documentation build configuration file, created by # sphinx-quickstart on Thu Jun 2 08:41:36 2016. # # This file is execfile()d with the current directory set to its # containing dir. # # Note that not all possible configuration values are present in this # autogenerated file. # # All configuration values have a default; values that are commented out # serve to show the default. # If extensions (or modules to document with autodoc) are in another directory, # add these directories to sys.path here. If the directory is relative to the # documentation root, use os.path.abspath to make it absolute, like shown here. # # import os # import sys # sys.path.insert(0, os.path.abspath('.')) from reversion import __version__ # -- General configuration ------------------------------------------------ # If your documentation needs a minimal Sphinx version, state it here. # # needs_sphinx = '1.0' # Add any Sphinx extension module names here, as strings. They can be # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom # ones. extensions = [] # Add any paths that contain templates here, relative to this directory. templates_path = [] # The suffix(es) of source filenames. # You can specify multiple suffix as a list of string: # # source_suffix = ['.rst', '.md'] source_suffix = '.rst' # The encoding of source files. # # source_encoding = 'utf-8-sig' # The master toctree document. master_doc = 'index' # General information about the project. project = 'django-reversion' copyright = '2016, Dave Hall' author = 'Dave Hall' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the # built documents. # # The short X.Y version. version = '.'.join(str(x) for x in __version__[:2]) # The full version, including alpha/beta/rc tags. release = '.'.join(str(x) for x in __version__) # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. # # This is also used if you do content translation via gettext catalogs. # Usually you set "language" from the command line for these cases. language = None # There are two options for replacing |today|: either, you set today to some # non-false value, then it is used: # # today = '' # # Else, today_fmt is used as the format for a strftime call. # # today_fmt = '%B %d, %Y' # List of patterns, relative to source directory, that match files and # directories to ignore when looking for source files. # This patterns also effect to html_static_path and html_extra_path exclude_patterns = ['_build', '_include', 'Thumbs.db', '.DS_Store'] # The reST default role (used for this markup: `text`) to use for all # documents. # # default_role = None # If true, '()' will be appended to :func: etc. cross-reference text. # # add_function_parentheses = True # If true, the current module name will be prepended to all description # unit titles (such as .. function::). # # add_module_names = True # If true, sectionauthor and moduleauthor directives will be shown in the # output. They are ignored by default. # # show_authors = False # The name of the Pygments (syntax highlighting) style to use. pygments_style = 'sphinx' # A list of ignored prefixes for module index sorting. # modindex_common_prefix = [] # If true, keep warnings as "system message" paragraphs in the built documents. # keep_warnings = False # If true, `todo` and `todoList` produce output, else they produce nothing. todo_include_todos = False # -- Options for HTML output ---------------------------------------------- # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. # # html_theme = 'alabaster' # Theme options are theme-specific and customize the look and feel of a theme # further. For a list of options available for each theme, see the # documentation. # # html_theme_options = {} # Add any paths that contain custom themes here, relative to this directory. # html_theme_path = [] # The name for this set of Sphinx documents. # " v documentation" by default. # # html_title = 'django-reversion v1.10.3' # A shorter title for the navigation bar. Default is the same as html_title. # # html_short_title = None # The name of an image file (relative to this directory) to place at the top # of the sidebar. # # html_logo = None # The name of an image file (relative to this directory) to use as a favicon of # the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 # pixels large. # # html_favicon = None # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". html_static_path = [] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied # directly to the root of the documentation. # # html_extra_path = [] # If not None, a 'Last updated on:' timestamp is inserted at every page # bottom, using the given strftime format. # The empty string is equivalent to '%b %d, %Y'. # # html_last_updated_fmt = None # If true, SmartyPants will be used to convert quotes and dashes to # typographically correct entities. # # html_use_smartypants = True # Custom sidebar templates, maps document names to template names. # # html_sidebars = {} # Additional templates that should be rendered to pages, maps page names to # template names. # # html_additional_pages = {} # If false, no module index is generated. # # html_domain_indices = True # If false, no index is generated. # # html_use_index = True # If true, the index is split into individual pages for each letter. # # html_split_index = False # If true, links to the reST sources are added to the pages. # # html_show_sourcelink = True # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. # # html_show_sphinx = True # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. # # html_show_copyright = True # If true, an OpenSearch description file will be output, and all pages will # contain a tag referring to it. The value of this option must be the # base URL from which the finished HTML is served. # # html_use_opensearch = '' # This is the file name suffix for HTML files (e.g. ".xhtml"). # html_file_suffix = None # Language to be used for generating the HTML full-text search index. # Sphinx supports the following languages: # 'da', 'de', 'en', 'es', 'fi', 'fr', 'h', 'it', 'ja' # 'nl', 'no', 'pt', 'ro', 'r', 'sv', 'tr', 'zh' # # html_search_language = 'en' # A dictionary with options for the search language support, empty by default. # 'ja' uses this config value. # 'zh' user can custom change `jieba` dictionary path. # # html_search_options = {'type': 'default'} # The name of a javascript file (relative to the configuration directory) that # implements a search results scorer. If empty, the default will be used. # # html_search_scorer = 'scorer.js' # Output file base name for HTML help builder. htmlhelp_basename = 'django-reversiondoc' # -- Options for LaTeX output --------------------------------------------- latex_elements = { # The paper size ('letterpaper' or 'a4paper'). # # 'papersize': 'letterpaper', # The font size ('10pt', '11pt' or '12pt'). # # 'pointsize': '10pt', # Additional stuff for the LaTeX preamble. # # 'preamble': '', # Latex figure (float) alignment # # 'figure_align': 'htbp', } # Grouping the document tree into LaTeX files. List of tuples # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ (master_doc, 'django-reversion.tex', 'django-reversion Documentation', 'Dave Hall', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of # the title page. # # latex_logo = None # For "manual" documents, if this is true, then toplevel headings are parts, # not chapters. # # latex_use_parts = False # If true, show page references after internal links. # # latex_show_pagerefs = False # If true, show URL addresses after external links. # # latex_show_urls = False # Documents to append as an appendix to all manuals. # # latex_appendices = [] # If false, no module index is generated. # # latex_domain_indices = True # -- Options for manual page output --------------------------------------- # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). man_pages = [ (master_doc, 'django-reversion', 'django-reversion Documentation', [author], 1) ] # If true, show URL addresses after external links. # # man_show_urls = False # -- Options for Texinfo output ------------------------------------------- # Grouping the document tree into Texinfo files. List of tuples # (source start file, target name, title, author, # dir menu entry, description, category) texinfo_documents = [ (master_doc, 'django-reversion', 'django-reversion Documentation', author, 'django-reversion', 'One line description of project.', 'Miscellaneous'), ] # Documents to append as an appendix to all manuals. # # texinfo_appendices = [] # If false, no module index is generated. # # texinfo_domain_indices = True # How to display URL addresses: 'footnote', 'no', or 'inline'. # # texinfo_show_urls = 'footnote' # If true, do not generate a @detailmenu in the "Top" node's menu. # # texinfo_no_detailmenu = False django-reversion-2.0.13/docs/django-versions.rst000066400000000000000000000012611323160775000216470ustar00rootroot00000000000000.. _django-versions: Compatible Django versions ========================== django-reversion aims to stay compatible with the latest LTS release of Django, along with more recent releases. See :ref:`changelog`. Older versions of Django require an older version of django-reversion to be installed. ============== ================= Django version Reversion release ============== ================= 1.8 - current 2.0.0 1.7 1.10.x 1.6 1.8.x ============== ================= .. Warning:: Older versions of django-reversion receive very limited support. It's advised to upgrade your Django to remain compatible with the latest release of django-reversion. django-reversion-2.0.13/docs/errors.rst000066400000000000000000000007331323160775000200560ustar00rootroot00000000000000.. _errors: Errors ====== django-reversion defines several custom errors. .. _RegistrationError: reversion.RegistrationError --------------------------- Something went wrong with the :ref:`registration-api`. .. _RevisionManagementError: reversion.RevisionManagementError --------------------------------- Something went wrong using the :ref:`revision-api`. .. _RevertError: reversion.RevertError --------------------- Something went wrong reverting a revision. django-reversion-2.0.13/docs/index.rst000066400000000000000000000022601323160775000176460ustar00rootroot00000000000000.. _index: django-reversion ================ **django-reversion** is an extension to the Django web framework that provides version control for model instances. Features -------- - Roll back to any point in a model instance's history. - Recover deleted model instances. - Simple admin integration. Installation ------------ To install django-reversion: 1. Install with pip: ``pip install django-reversion``. 2. Add ``'reversion'`` to ``INSTALLED_APPS``. 3. Run ``manage.py migrate``. .. Important:: See :ref:`django-versions` if you're not using the latest release of Django. Admin integration ----------------- django-reversion can be used to add rollback and recovery to your admin site. .. include:: /_include/admin.rst For more information about admin integration, see :ref:`admin`. Low-level API ------------- You can use the django-reversion API to build version-controlled applications. See :ref:`api`. More information ---------------- Installation ^^^^^^^^^^^^ .. toctree:: :maxdepth: 1 django-versions common-problems changelog Usage ^^^^^ .. toctree:: :maxdepth: 2 admin commands api views middleware errors signals django-reversion-2.0.13/docs/middleware.rst000066400000000000000000000017341323160775000206610ustar00rootroot00000000000000.. _middleware: Middleware ========== Shortcuts when using django-reversion in views. reversion.middleware.RevisionMiddleware --------------------------------------- Wrap the every request that isn't ``GET``, ``HEAD`` or ``OPTIONS`` in a revision block. The request user will also be added to the revision metadata. To enable ``RevisionMiddleware``, add ``'reversion.middleware.RevisionMiddleware'`` to your ``MIDDLEWARE_CLASSES`` setting. For Django >= 1.10, add it to your ``MIDDLEWARE`` setting. .. Warning:: This will wrap every request that isn't ``GET``, ``HEAD`` or ``OPTIONS`` in a database transaction. For best performance, consider marking individual views instead. ``RevisionMiddleware.manage_manually = False`` .. include:: /_include/create-revision-manage-manually.rst ``RevisionMiddleware.using = None`` .. include:: /_include/create-revision-using.rst ``RevisionMiddleware.atomic = True`` .. include:: /_include/create-revision-atomic.rst django-reversion-2.0.13/docs/signals.rst000066400000000000000000000007021323160775000201760ustar00rootroot00000000000000.. _signals: Signals ======= django-reversion provides two custom signals. reversion.signals.pre_revision_commit ------------------------------------- Sent just before a revision is saved to the database. .. include:: /_include/signal-args.rst reversion.signals.post_revision_commit -------------------------------------- Sent just after a revision and its related versions are saved to the database. .. include:: /_include/signal-args.rst django-reversion-2.0.13/docs/views.rst000066400000000000000000000023541323160775000177000ustar00rootroot00000000000000.. _views: Views ===== Shortcuts when using django-reversion in views. Decorators ---------- ``reversion.views.create_revision(manage_manually=False, using=None, atomic=True)`` Decorates a view to wrap every request that isn't ``GET``, ``HEAD`` or ``OPTIONS`` in a revision block. The request user will also be added to the revision metadata. You can set the revision comment by calling :ref:`reversion.set_comment() ` within your view. .. include:: /_include/create-revision-args.rst reversion.views.RevisionMixin ----------------------------- Mixin a class-based view to wrap every request that isn't ``GET``, ``HEAD`` or ``OPTIONS`` in a revision block. The request user will also be added to the revision metadata. You can set the revision comment by calling :ref:`reversion.set_comment() ` within your view. .. code:: python from django.contrib.auth.views import FormView from reversion.views import RevisionMixin class RevisionFormView(RevisionMixin, FormView): pass ``RevisionMixin.revision_manage_manually = False`` .. include:: /_include/create-revision-manage-manually.rst ``RevisionMixin.revision_using = None`` .. include:: /_include/create-revision-using.rst django-reversion-2.0.13/reversion/000077500000000000000000000000001323160775000170715ustar00rootroot00000000000000django-reversion-2.0.13/reversion/__init__.py000066400000000000000000000016331323160775000212050ustar00rootroot00000000000000""" An extension to the Django web framework that provides version control for model instances. Developed by Dave Hall. """ try: import django # noqa except ImportError: # pragma: no cover # The top-level API requires Django, which might not be present if setup.py # is importing reversion to get __version__. pass else: from reversion.errors import ( # noqa RevertError, RevisionManagementError, RegistrationError, ) from reversion.revisions import ( # noqa is_active, is_manage_manually, get_user, set_user, get_comment, set_comment, get_date_created, set_date_created, add_meta, add_to_revision, create_revision, register, is_registered, unregister, get_registered_models, ) __version__ = VERSION = (2, 0, 13) django-reversion-2.0.13/reversion/admin.py000066400000000000000000000322021323160775000205320ustar00rootroot00000000000000from __future__ import unicode_literals import json from contextlib import contextmanager from django.db import models, transaction, connection from django.conf.urls import url from django.contrib import admin, messages from django.contrib.admin import options from django.contrib.admin.models import LogEntry from django.contrib.admin.utils import unquote, quote try: from django.contrib.contenttypes.admin import GenericInlineModelAdmin from django.contrib.contenttypes.fields import GenericRelation except ImportError: # Django < 1.9 pragma: no cover from django.contrib.contenttypes.generic import GenericInlineModelAdmin, GenericRelation try: from django.urls import reverse except ImportError: # Django < 1.10 pragma: no cover from django.core.urlresolvers import reverse from django.core.exceptions import PermissionDenied, ImproperlyConfigured from django.shortcuts import get_object_or_404, render, redirect from django.utils.text import capfirst from django.utils.timezone import template_localtime from django.utils.translation import ugettext as _ from django.utils.encoding import force_text from django.utils.formats import localize from reversion.compat import remote_field, remote_model from reversion.errors import RevertError from reversion.models import Version from reversion.revisions import is_active, register, is_registered, set_comment, create_revision, set_user from reversion.views import _RollBackRevisionView def private_fields(meta): try: return meta.private_fields except AttributeError: # Django < 1.10 pragma: no cover return meta.virtual_fields class VersionAdmin(admin.ModelAdmin): object_history_template = "reversion/object_history.html" change_list_template = "reversion/change_list.html" revision_form_template = None recover_list_template = None recover_form_template = None history_latest_first = False def reversion_register(self, model, **kwargs): """Registers the model with reversion.""" register(model, **kwargs) @contextmanager def create_revision(self, request): with create_revision(): set_user(request.user) yield # Revision helpers. def _reversion_get_template_list(self, template_name): opts = self.model._meta return ( "reversion/%s/%s/%s" % (opts.app_label, opts.object_name.lower(), template_name), "reversion/%s/%s" % (opts.app_label, template_name), "reversion/%s" % template_name, ) def _reversion_order_version_queryset(self, queryset): """Applies the correct ordering to the given version queryset.""" if not self.history_latest_first: queryset = queryset.order_by("pk") return queryset # Messages. def log_addition(self, request, object, change_message=None): change_message = change_message or _("Initial version.") if is_active(): # If https://code.djangoproject.com/ticket/27218 is implemented, we # could first call super() and get the change_message from the returned # LogEntry. if isinstance(change_message, list): set_comment(LogEntry(change_message=json.dumps(change_message)).get_change_message()) else: set_comment(change_message) try: super(VersionAdmin, self).log_addition(request, object, change_message) except TypeError: # Django < 1.9 pragma: no cover super(VersionAdmin, self).log_addition(request, object) def log_change(self, request, object, message): if is_active(): if isinstance(message, list): set_comment(LogEntry(change_message=json.dumps(message)).get_change_message()) else: set_comment(message) super(VersionAdmin, self).log_change(request, object, message) # Auto-registration. def _reversion_autoregister(self, model, follow): if not is_registered(model): for parent_model, field in model._meta.concrete_model._meta.parents.items(): follow += (field.name,) self._reversion_autoregister(parent_model, ()) self.reversion_register(model, follow=follow) def _reversion_introspect_inline_admin(self, inline): inline_model = None follow_field = None fk_name = None if issubclass(inline, GenericInlineModelAdmin): inline_model = inline.model ct_field = inline.ct_field fk_name = inline.ct_fk_field for field in private_fields(self.model._meta): if ( isinstance(field, GenericRelation) and remote_model(field) == inline_model and field.object_id_field_name == fk_name and field.content_type_field_name == ct_field ): follow_field = field.name break elif issubclass(inline, options.InlineModelAdmin): inline_model = inline.model fk_name = inline.fk_name if not fk_name: for field in inline_model._meta.get_fields(): if ( isinstance(field, (models.ForeignKey, models.OneToOneField)) and issubclass(self.model, remote_model(field)) ): fk_name = field.name break if fk_name and not remote_field(inline_model._meta.get_field(fk_name)).is_hidden(): field = inline_model._meta.get_field(fk_name) accessor = remote_field(field).get_accessor_name() follow_field = accessor return inline_model, follow_field def __init__(self, *args, **kwargs): super(VersionAdmin, self).__init__(*args, **kwargs) # Automatically register models if required. if not is_registered(self.model): inline_fields = () for inline in self.inlines: inline_model, follow_field = self._reversion_introspect_inline_admin(inline) if inline_model: self._reversion_autoregister(inline_model, ()) if follow_field: inline_fields += (follow_field,) self._reversion_autoregister(self.model, inline_fields) def get_urls(self): urls = super(VersionAdmin, self).get_urls() admin_site = self.admin_site opts = self.model._meta info = opts.app_label, opts.model_name, reversion_urls = [ url("^recover/$", admin_site.admin_view(self.recoverlist_view), name='%s_%s_recoverlist' % info), url("^recover/(\d+)/$", admin_site.admin_view(self.recover_view), name='%s_%s_recover' % info), url("^([^/]+)/history/(\d+)/$", admin_site.admin_view(self.revision_view), name='%s_%s_revision' % info), ] return reversion_urls + urls # Views. def add_view(self, request, form_url='', extra_context=None): with self.create_revision(request): return super(VersionAdmin, self).add_view(request, form_url, extra_context) def change_view(self, request, object_id, form_url='', extra_context=None): with self.create_revision(request): return super(VersionAdmin, self).change_view(request, object_id, form_url, extra_context) def _reversion_revisionform_view(self, request, version, template_name, extra_context=None): # Check that database transactions are supported. if not connection.features.uses_savepoints: raise ImproperlyConfigured("Cannot use VersionAdmin with a database that does not support savepoints.") # Run the view. try: with transaction.atomic(using=version.db): # Revert the revision. version.revision.revert(delete=True) # Run the normal changeform view. with self.create_revision(request): response = self.changeform_view(request, quote(version.object_id), request.path, extra_context) # Decide on whether the keep the changes. if request.method == "POST" and response.status_code == 302: set_comment(_("Reverted to previous version, saved on %(datetime)s") % { "datetime": localize(template_localtime(version.revision.date_created)), }) else: response.template_name = template_name # Set the template name to the correct template. response.render() # Eagerly render the response, so it's using the latest version. raise _RollBackRevisionView(response) # Raise exception to undo the transaction and revision. except RevertError as ex: opts = self.model._meta messages.error(request, force_text(ex)) return redirect("{}:{}_{}_changelist".format(self.admin_site.name, opts.app_label, opts.model_name)) except _RollBackRevisionView as ex: return ex.response return response def recover_view(self, request, version_id, extra_context=None): """Displays a form that can recover a deleted model.""" # The revisionform view will check for change permission (via changeform_view), # but we also need to check for add permissions here. if not self.has_add_permission(request): raise PermissionDenied # Render the recover view. version = get_object_or_404(Version, pk=version_id) context = { "title": _("Recover %(name)s") % {"name": version.object_repr}, "recover": True, } context.update(extra_context or {}) return self._reversion_revisionform_view( request, version, self.recover_form_template or self._reversion_get_template_list("recover_form.html"), context, ) def revision_view(self, request, object_id, version_id, extra_context=None): """Displays the contents of the given revision.""" object_id = unquote(object_id) # Underscores in primary key get quoted to "_5F" version = get_object_or_404(Version, pk=version_id, object_id=object_id) context = { "title": _("Revert %(name)s") % {"name": version.object_repr}, "revert": True, } context.update(extra_context or {}) return self._reversion_revisionform_view( request, version, self.revision_form_template or self._reversion_get_template_list("revision_form.html"), context, ) def changelist_view(self, request, extra_context=None): with self.create_revision(request): context = { "has_change_permission": self.has_change_permission(request), } context.update(extra_context or {}) return super(VersionAdmin, self).changelist_view(request, context) def recoverlist_view(self, request, extra_context=None): """Displays a deleted model to allow recovery.""" # Check if user has change and add permissions for model if not self.has_change_permission(request) or not self.has_add_permission(request): raise PermissionDenied model = self.model opts = model._meta deleted = self._reversion_order_version_queryset(Version.objects.get_deleted(self.model)) # Set the app name. request.current_app = self.admin_site.name # Get the rest of the context. context = dict( self.admin_site.each_context(request), opts=opts, app_label=opts.app_label, module_name=capfirst(opts.verbose_name), title=_("Recover deleted %(name)s") % {"name": force_text(opts.verbose_name_plural)}, deleted=deleted, ) context.update(extra_context or {}) return render( request, self.recover_list_template or self._reversion_get_template_list("recover_list.html"), context, ) def history_view(self, request, object_id, extra_context=None): """Renders the history view.""" # Check if user has change permissions for model if not self.has_change_permission(request): raise PermissionDenied opts = self.model._meta action_list = [ { "revision": version.revision, "url": reverse( "%s:%s_%s_revision" % (self.admin_site.name, opts.app_label, opts.model_name), args=(quote(version.object_id), version.id) ), } for version in self._reversion_order_version_queryset(Version.objects.get_for_object_reference( self.model, unquote(object_id), # Underscores in primary key get quoted to "_5F" ).select_related("revision__user")) ] # Compile the context. context = {"action_list": action_list} context.update(extra_context or {}) return super(VersionAdmin, self).history_view(request, object_id, context) django-reversion-2.0.13/reversion/compat.py000066400000000000000000000007021323160775000207250ustar00rootroot00000000000000import django def remote_field(field): # remote_field is new in Django 1.9 return field.remote_field if hasattr(field, 'remote_field') else field.rel def remote_model(field): # remote_field is new in Django 1.9 return field.remote_field.model if hasattr(field, 'remote_field') else field.rel.to def is_authenticated(user): if django.VERSION < (1, 10): return user.is_authenticated() return user.is_authenticated django-reversion-2.0.13/reversion/errors.py000066400000000000000000000005451323160775000207630ustar00rootroot00000000000000class RevertError(Exception): """Exception thrown when something goes wrong with reverting a model.""" class RevisionManagementError(Exception): """Exception that is thrown when something goes wrong with revision managment.""" class RegistrationError(Exception): """Exception thrown when registration with django-reversion goes wrong.""" django-reversion-2.0.13/reversion/locale/000077500000000000000000000000001323160775000203305ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/ar/000077500000000000000000000000001323160775000207325ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/ar/LC_MESSAGES/000077500000000000000000000000001323160775000225175ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/ar/LC_MESSAGES/django.mo000066400000000000000000000051151323160775000243200ustar00rootroot00000000000000Ţ•Ě|đLńQ> ˘ŞŻBŔDHYr‚3šPÎ(XHˇ¦ ®»ľŔplđ]l‡–§FĂB M)cŤť=»Zů<T p‘   " <     Choose a date from the list below to recover a deleted version of an object.Choose a date from the list below to revert to a previous version of this object.CommentDate/timeHistoryHomeInitial version.Press the save button below to recover this version of the object.Press the save button below to revert to this version of the object.Recover %(name)sRecover deleted %(name)sRevert %(name)sRevert %(verbose_name)sReverted to previous version, saved on %(datetime)sThe %(model)s "%(name)s" was reverted successfully. You may edit it again below.There are no deleted objects to recover.This object doesn't have a change history. It probably wasn't added via this admin site.Usercommentdate createduserProject-Id-Version: PACKAGE VERSION Report-Msgid-Bugs-To: POT-Creation-Date: 2015-06-15 01:49+0000 PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE Last-Translator: FULL NAME Language-Team: LANGUAGE Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5; أختر تاريخ من القائمه أدناه لإسترجاع نسخه سابقه من هذا الŮيانأختر تاريخ من القائمه أدناه لأعاده نسخه سابقه من هذا الŮيانالتعليقالتاريخ/ الŮقتالتاريخالرئيسيهالنسخة الأŮليةأنقر على Ř­Ůظ أدناه لأسترجاع هذه النسخهأنقر على Ř­Ůظ أدناه لإعاده هذه النسخهإستعيد %(name)sأستعيد المحذŮ٠من %(name)sأعد %(name)sإسترجع %(verbose_name)sاُعيد لنسخه سابقه، Ř­ŮŹŮظ ŮŮŠ %(datetime)sŘŞŮ… أعاده %(model)s "%(name)s" بنجاح ŘŚ ŮŠŮ…ŮنŮ/ŮŠ التعديل مجددالا ŮŠŮجد Ůيانات محذŮŮه لإسترجاعهالا ŮŠŮجد تاريخ تعديل لهذا الŮيان. ربما لم يُنشأ من Ů…Ůقع الإدارهالمستخدمالتعليقتاريخ الأنشاءالمستخدمdjango-reversion-2.0.13/reversion/locale/ar/LC_MESSAGES/django.po000066400000000000000000000100331323160775000243160ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-06-15 01:49+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 " "&& n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n" #: reversion/admin.py:161 msgid "Initial version." msgstr "النسخة الأŮلية" #: reversion/admin.py:195 reversion/templates/reversion/change_list.html:7 #: reversion/templates/reversion/recover_form.html:10 #: reversion/templates/reversion/recover_list.html:10 #, python-format msgid "Recover deleted %(name)s" msgstr "أستعيد المحذŮ٠من %(name)s" #: reversion/admin.py:312 #, python-format msgid "Reverted to previous version, saved on %(datetime)s" msgstr "اُعيد لنسخه سابقه، Ř­ŮŹŮظ ŮŮŠ %(datetime)s" #: reversion/admin.py:314 #, python-format msgid "" "The %(model)s \"%(name)s\" was reverted successfully. You may edit it again " "below." msgstr "" "ŘŞŮ… أعاده %(model)s \"%(name)s\" بنجاح ŘŚ ŮŠŮ…ŮنŮ/ŮŠ التعديل مجددا" "" #: reversion/admin.py:399 #, python-format msgid "Recover %(name)s" msgstr "إستعيد %(name)s" #: reversion/admin.py:413 #, python-format msgid "Revert %(name)s" msgstr "أعد %(name)s" #: reversion/models.py:59 msgid "date created" msgstr "تاريخ الأنشاء" #: reversion/models.py:66 msgid "user" msgstr "المستخدم" #: reversion/models.py:70 msgid "comment" msgstr "التعليق" #: reversion/templates/reversion/object_history.html:8 msgid "" "Choose a date from the list below to revert to a previous version of this " "object." msgstr "أختر تاريخ من القائمه أدناه لأعاده نسخه سابقه من هذا الŮيان" #: reversion/templates/reversion/object_history.html:15 #: reversion/templates/reversion/recover_list.html:23 msgid "Date/time" msgstr "التاريخ/ الŮقت" #: reversion/templates/reversion/object_history.html:16 msgid "User" msgstr "المستخدم" #: reversion/templates/reversion/object_history.html:17 msgid "Comment" msgstr "التعليق" #: reversion/templates/reversion/object_history.html:38 msgid "" "This object doesn't have a change history. It probably wasn't added via this " "admin site." msgstr "لا ŮŠŮجد تاريخ تعديل لهذا الŮيان. ربما لم يُنشأ من Ů…Ůقع الإداره" #: reversion/templates/reversion/recover_form.html:7 #: reversion/templates/reversion/recover_list.html:7 #: reversion/templates/reversion/revision_form.html:7 msgid "Home" msgstr "الرئيسيه" #: reversion/templates/reversion/recover_form.html:17 msgid "Press the save button below to recover this version of the object." msgstr "أنقر على Ř­Ůظ أدناه لأسترجاع هذه النسخه" #: reversion/templates/reversion/recover_list.html:17 msgid "" "Choose a date from the list below to recover a deleted version of an object." msgstr "أختر تاريخ من القائمه أدناه لإسترجاع نسخه سابقه من هذا الŮيان" #: reversion/templates/reversion/recover_list.html:37 msgid "There are no deleted objects to recover." msgstr "لا ŮŠŮجد Ůيانات محذŮŮه لإسترجاعها" #: reversion/templates/reversion/revision_form.html:11 msgid "History" msgstr "التاريخ" #: reversion/templates/reversion/revision_form.html:12 #, python-format msgid "Revert %(verbose_name)s" msgstr "إسترجع %(verbose_name)s" #: reversion/templates/reversion/revision_form.html:25 msgid "Press the save button below to revert to this version of the object." msgstr "أنقر على Ř­Ůظ أدناه لإعاده هذه النسخه" django-reversion-2.0.13/reversion/locale/cs/000077500000000000000000000000001323160775000207355ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/cs/LC_MESSAGES/000077500000000000000000000000001323160775000225225ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/cs/LC_MESSAGES/django.mo000066400000000000000000000046521323160775000243300ustar00rootroot00000000000000Ţ•Ě|đ ńLţQKťĄ µżÇĚBÝD ev ʰŔ3ŘP (]X†ßuäZDkN° ˙  %. 4BAB„ÇŘ!ň).>6m`¤& s,       Add %(name)sChoose a date from the list below to recover a deleted version of an object.Choose a date from the list below to revert to a previous version of this object.CommentDATETIME_FORMATDate/timeHistoryHomeInitial version.Press the save button below to recover this version of the object.Press the save button below to revert to this version of the object.Recover %(name)sRecover deleted %(name)sRecover deleted %(verbose_name)sRevert %(name)sRevert %(verbose_name)sReverted to previous version, saved on %(datetime)sThe %(model)s "%(name)s" was reverted successfully. You may edit it again below.There are no deleted objects to recover.This object doesn't have a change history. It probably wasn't added via this admin site.UserProject-Id-Version: PACKAGE VERSION Report-Msgid-Bugs-To: POT-Creation-Date: 2011-01-12 11:13+0100 PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE Last-Translator: FULL NAME Language-Team: LANGUAGE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=3; plural=n==1 ? 0 : n>1 && n<5 ? 1 : 2; PĹ™idat %(name)sZvolte datum ze seznamu nĂ­Ĺľe pro obnovenĂ­ smazanĂ© verze objektu.Zvolte datum ze seznamu nĂ­Ĺľe pro návrat k pĹ™edchozĂ­ verzi tohoto objektu.KomentářDATETIME_FORMATDatum/ÄŤasHistorieDomĹŻPrvnĂ­ verzeKliknÄ›te na tlaÄŤĂ­tko uloĹľit pro obnovenĂ­ tĂ©to verze objektu.KliknÄ›te na tlaÄŤĂ­tko uloĹľit pro návrat k tĂ©to verzi objektu.Obnovit %(name)sObnovit smazanĂ© %(name)sObnovit smazanĂ© %(verbose_name)sNavrátit se k pĹ™edchozĂ­ verzi %(name)sNavrátit %(verbose_name)s k pĹ™edchozĂ­ verziVráceno do pĹ™edchozĂ­ verze uloĹľenĂ© v %(datetime)sObjekt %(model)s "%(name)s" byl ĂşspěšnÄ› obnoven. MĹŻĹľete ho znovu zaÄŤĂ­t upravovat nĂ­Ĺľe.ŽádnĂ© smazanĂ© objekty k obnovenĂ­.Tento objekt nemá uloĹľenou žádnou historii zmÄ›n. ZĹ™ejmÄ› nebyl pĹ™idát pĹ™es toto administraÄŤnĂ­ rozhranĂ­.UĹľivateldjango-reversion-2.0.13/reversion/locale/cs/LC_MESSAGES/django.po000066400000000000000000000074071323160775000243340ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2011-01-12 11:13+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=n==1 ? 0 : n>1 && n<5 ? 1 : 2;\n" #: admin.py:112 templates/reversion/change_list.html:8 #: templates/reversion/recover_list.html:10 #, python-format msgid "Recover deleted %(name)s" msgstr "Obnovit smazanĂ© %(name)s" #: admin.py:165 #, python-format msgid "Reverted to previous version, saved on %(datetime)s" msgstr "Vráceno do pĹ™edchozĂ­ verze uloĹľenĂ© v %(datetime)s" #: admin.py:167 #, python-format msgid "" "The %(model)s \"%(name)s\" was reverted successfully. You may edit it again " "below." msgstr "" "Objekt %(model)s \"%(name)s\" byl ĂşspěšnÄ› obnoven. MĹŻĹľete ho znovu zaÄŤĂ­t upravovat " "nĂ­Ĺľe." #: admin.py:273 #, python-format msgid "Recover %(name)s" msgstr "Obnovit %(name)s" #: admin.py:284 #, python-format msgid "Revert %(name)s" msgstr "Navrátit se k pĹ™edchozĂ­ verzi %(name)s" #: management/commands/createinitialrevisions.py:76 msgid "Initial version." msgstr "PrvnĂ­ verze" #: templates/reversion/change_list.html:11 #, python-format msgid "Add %(name)s" msgstr "PĹ™idat %(name)s" #: templates/reversion/object_history.html:8 msgid "" "Choose a date from the list below to revert to a previous version of this " "object." msgstr "" "Zvolte datum ze seznamu nĂ­Ĺľe pro návrat k pĹ™edchozĂ­ verzi tohoto objektu." #: templates/reversion/object_history.html:15 #: templates/reversion/recover_list.html:23 msgid "Date/time" msgstr "Datum/ÄŤas" #: templates/reversion/object_history.html:16 msgid "User" msgstr "UĹľivatel" #: templates/reversion/object_history.html:17 msgid "Comment" msgstr "Komentář" #: templates/reversion/object_history.html:23 #: templates/reversion/recover_list.html:30 msgid "DATETIME_FORMAT" msgstr "DATETIME_FORMAT" #: templates/reversion/object_history.html:31 msgid "" "This object doesn't have a change history. It probably wasn't added via this " "admin site." msgstr "" "Tento objekt nemá uloĹľenou žádnou historii zmÄ›n. ZĹ™ejmÄ› nebyl pĹ™idát pĹ™es toto " "administraÄŤnĂ­ rozhranĂ­." #: templates/reversion/recover_form.html:7 #: templates/reversion/recover_list.html:7 #: templates/reversion/revision_form.html:10 msgid "Home" msgstr "DomĹŻ" #: templates/reversion/recover_form.html:10 #, python-format msgid "Recover deleted %(verbose_name)s" msgstr "Obnovit smazanĂ© %(verbose_name)s" #: templates/reversion/recover_form.html:17 msgid "Press the save button below to recover this version of the object." msgstr "KliknÄ›te na tlaÄŤĂ­tko uloĹľit pro obnovenĂ­ tĂ©to verze objektu." #: templates/reversion/recover_list.html:17 msgid "" "Choose a date from the list below to recover a deleted version of an object." msgstr "" "Zvolte datum ze seznamu nĂ­Ĺľe pro obnovenĂ­ smazanĂ© verze objektu." #: templates/reversion/recover_list.html:37 msgid "There are no deleted objects to recover." msgstr "ŽádnĂ© smazanĂ© objekty k obnovenĂ­." #: templates/reversion/revision_form.html:14 msgid "History" msgstr "Historie" #: templates/reversion/revision_form.html:15 #, python-format msgid "Revert %(verbose_name)s" msgstr "Navrátit %(verbose_name)s k pĹ™edchozĂ­ verzi" #: templates/reversion/revision_form.html:28 msgid "Press the save button below to revert to this version of the object." msgstr "KliknÄ›te na tlaÄŤĂ­tko uloĹľit pro návrat k tĂ©to verzi objektu." django-reversion-2.0.13/reversion/locale/da/000077500000000000000000000000001323160775000207145ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/da/LC_MESSAGES/000077500000000000000000000000001323160775000225015ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/da/LC_MESSAGES/django.mo000066400000000000000000000045201323160775000243010ustar00rootroot00000000000000Ţ•Ě|đLńQ> ˘ŞŻBŔDHYr‚3šPÎ(XHˇ¦ ®»kŔX,_… ĺďřIKa­ľ×ę6V</“dĂ( / 9 I     Choose a date from the list below to recover a deleted version of an object.Choose a date from the list below to revert to a previous version of this object.CommentDate/timeHistoryHomeInitial version.Press the save button below to recover this version of the object.Press the save button below to revert to this version of the object.Recover %(name)sRecover deleted %(name)sRevert %(name)sRevert %(verbose_name)sReverted to previous version, saved on %(datetime)sThe %(model)s "%(name)s" was reverted successfully. You may edit it again below.There are no deleted objects to recover.This object doesn't have a change history. It probably wasn't added via this admin site.Usercommentdate createduserProject-Id-Version: PACKAGE VERSION Report-Msgid-Bugs-To: POT-Creation-Date: 2014-07-30 11:17+0200 PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE Last-Translator: FULL NAME Language-Team: LANGUAGE Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); Vælg en dato fra listen her under for at gendanne til en tidligere version af objektet.Vælg en dato fra listen her under for at Revertere til en tidligere version af det her objekt.KommentarDato/tidHistorikHjemFørste version.Tryk pĂĄ gem knappen nedenunder for at genskab denne version af objektet.Tryk pĂĄ gem her nedenunder for at revertere til denne version af objektet.Genskab %(name)sGendan slettede %(name)sRevertere %(name)sRevertere %(verbose_name)sGendannet til tidligere version, gemt den %(datetime)sGendannelsen af %(model)s "%(name)s" var succesfuld. Du kan redigere den igenher underDer findes inden slettede objekter at gendanne.Det her objekt har ingen ændringshistorik. Det er sandsynligvis ikke tilføjet viadette admin-side.Brugerkommentaroprettelsesdatobrugerdjango-reversion-2.0.13/reversion/locale/da/LC_MESSAGES/django.po000066400000000000000000000070171323160775000243100ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-07-30 11:17+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: admin.py:160 msgid "Initial version." msgstr "Første version." #: admin.py:194 templates/reversion/change_list.html:7 #: templates/reversion/recover_form.html:11 #: templates/reversion/recover_list.html:11 #, python-format msgid "Recover deleted %(name)s" msgstr "Gendan slettede %(name)s" #: admin.py:311 #, python-format msgid "Reverted to previous version, saved on %(datetime)s" msgstr "Gendannet til tidligere version, gemt den %(datetime)s" #: admin.py:313 #, python-format msgid "" "The %(model)s \"%(name)s\" was reverted successfully. You may edit it again " "below." msgstr "" "Gendannelsen af %(model)s \"%(name)s\" var succesfuld. Du kan redigere den igen" "her under" #: admin.py:398 #, python-format msgid "Recover %(name)s" msgstr "Genskab %(name)s" #: admin.py:412 #, python-format msgid "Revert %(name)s" msgstr "Revertere %(name)s" #: models.py:55 msgid "date created" msgstr "oprettelsesdato" #: models.py:62 msgid "user" msgstr "bruger" #: models.py:66 msgid "comment" msgstr "kommentar" #: templates/reversion/object_history.html:8 msgid "Choose a date from the list below to revert to a previous version of this object." msgstr "Vælg en dato fra listen her under for at Revertere til en tidligere version af det her objekt." #: templates/reversion/object_history.html:15 #: templates/reversion/recover_list.html:24 msgid "Date/time" msgstr "Dato/tid" #: templates/reversion/object_history.html:16 msgid "User" msgstr "Bruger" #: templates/reversion/object_history.html:17 msgid "Comment" msgstr "Kommentar" #: templates/reversion/object_history.html:38 msgid "" "This object doesn't have a change history. It probably wasn't added via this " "admin site." msgstr "" "Det her objekt har ingen ændringshistorik. Det er sandsynligvis ikke tilføjet via" "dette admin-side." #: templates/reversion/recover_form.html:8 #: templates/reversion/recover_list.html:8 #: templates/reversion/revision_form.html:8 msgid "Home" msgstr "Hjem" #: templates/reversion/recover_form.html:18 msgid "Press the save button below to recover this version of the object." msgstr "Tryk pĂĄ gem knappen nedenunder for at genskab denne version af objektet." #: templates/reversion/recover_list.html:18 msgid "Choose a date from the list below to recover a deleted version of an object." msgstr "Vælg en dato fra listen her under for at gendanne til en tidligere version af objektet." #: templates/reversion/recover_list.html:38 msgid "There are no deleted objects to recover." msgstr "Der findes inden slettede objekter at gendanne." #: templates/reversion/revision_form.html:12 msgid "History" msgstr "Historik" #: templates/reversion/revision_form.html:13 #, python-format msgid "Revert %(verbose_name)s" msgstr "Revertere %(verbose_name)s" #: templates/reversion/revision_form.html:26 msgid "Press the save button below to revert to this version of the object." msgstr "Tryk pĂĄ gem her nedenunder for at revertere til denne version af objektet." django-reversion-2.0.13/reversion/locale/de/000077500000000000000000000000001323160775000207205ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/de/LC_MESSAGES/000077500000000000000000000000001323160775000225055ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/de/LC_MESSAGES/django.mo000066400000000000000000000050471323160775000243120ustar00rootroot00000000000000ޕԌ LQcµ˝ Í×ßäBőD8} Ž™ ˛Óă3űP/(€X©8@tU}Ę H R ^ itz>’=Ń)$=,bʦ>Ĺa Bf t©      Add %(name)sChoose a date from the list below to recover a deleted version of an object.Choose a date from the list below to revert to a previous version of this object.CommentDATETIME_FORMATDate/timeHistoryHomeInitial version.Press the save button below to recover this version of the object.Press the save button below to revert to this version of the object.Recover %(name)sRecover %sRecover deleted %(name)sRecover deleted %(verbose_name)sRevert %(name)sRevert %(verbose_name)sReverted to previous version, saved on %(datetime)sThe %(model)s "%(name)s" was reverted successfully. You may edit it again below.There are no deleted objects to recover.This object doesn't have a change history. It probably wasn't added via this admin site.UserProject-Id-Version: reversion Report-Msgid-Bugs-To: POT-Creation-Date: 2009-02-03 08:31+0100 PO-Revision-Date: 2009-02-03 08:41+0100 Last-Translator: Jannis Leidel Language-Team: LANGUAGE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit %(name)s hinzufĂĽgenWählen Sie einen Zeitpunk aus der untenstehenden Liste, um eine gelöschte Version des Objektes wiederherzustellen.Wählen Sie einen Zeitpunkt aus der untenstehenden Liste aus, um zu einer vorherigen Version dieses Objektes zurĂĽckzukehren.Kommentarj. N Y, H:iDatum/ZeitGeschichteStartUrsprĂĽngliche Version.Sichern Sie, um diese Version des Objektes wiederherzustellen.Sichern Sie, um das Objekt zu dieser Version zurĂĽckzusetzen.%(name)s wiederherstellen%s wiederherstellenGelöschte %(name)s wiederherstellenGelöschte %(verbose_name)s wiederherstellen%(name)s zurĂĽcksetzen%(verbose_name)s zurĂĽcksetzenZu vorheriger Version zurĂĽckgesetzt, %(datetime)s gespeichert%(model)s "%(name)s" wurde erfolgreich zurĂĽckgesetzt. Sie können mit der Bearbeitung forfahren.Es sind keine gelöschten Objekte zur Wiederherstellung vorhanden.Dieses Objekt hat keine Ă„nderungsgeschichte. Es wurde möglicherweise nicht ĂĽber diese Verwaltungsseiten angelegt.Benutzerdjango-reversion-2.0.13/reversion/locale/de/LC_MESSAGES/django.po000066400000000000000000000076751323160775000243260ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: reversion\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2009-02-03 08:31+0100\n" "PO-Revision-Date: 2009-02-03 08:41+0100\n" "Last-Translator: Jannis Leidel \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: admin.py:122 templates/reversion/change_list.html:8 #: templates/reversion/recover_list.html:9 #, python-format msgid "Recover deleted %(name)s" msgstr "Gelöschte %(name)s wiederherstellen" #: admin.py:155 #, python-format msgid "Reverted to previous version, saved on %(datetime)s" msgstr "Zu vorheriger Version zurĂĽckgesetzt, %(datetime)s gespeichert" #: admin.py:157 #, python-format msgid "" "The %(model)s \"%(name)s\" was reverted successfully. You may edit it again " "below." msgstr "" "%(model)s \"%(name)s\" wurde erfolgreich zurĂĽckgesetzt. Sie können mit der " "Bearbeitung forfahren." #: admin.py:227 #, python-format msgid "Recover %s" msgstr "%s wiederherstellen" #: admin.py:243 #, python-format msgid "Revert %(name)s" msgstr "%(name)s zurĂĽcksetzen" #: management/commands/createinitialrevisions.py:76 msgid "Initial version." msgstr "UrsprĂĽngliche Version." #: templates/reversion/change_list.html:11 #, python-format msgid "Add %(name)s" msgstr "%(name)s hinzufĂĽgen" #: templates/reversion/object_history.html:8 msgid "" "Choose a date from the list below to revert to a previous version of this " "object." msgstr "" "Wählen Sie einen Zeitpunkt aus der untenstehenden Liste aus, um zu einer " "vorherigen Version dieses Objektes zurĂĽckzukehren." #: templates/reversion/object_history.html:15 #: templates/reversion/recover_list.html:21 msgid "Date/time" msgstr "Datum/Zeit" #: templates/reversion/object_history.html:16 msgid "User" msgstr "Benutzer" #: templates/reversion/object_history.html:17 msgid "Comment" msgstr "Kommentar" #: templates/reversion/object_history.html:23 #: templates/reversion/recover_list.html:28 msgid "DATETIME_FORMAT" msgstr "j. N Y, H:i" #: templates/reversion/object_history.html:31 msgid "" "This object doesn't have a change history. It probably wasn't added via this " "admin site." msgstr "" "Dieses Objekt hat keine Ă„nderungsgeschichte. Es wurde möglicherweise nicht " "ĂĽber diese Verwaltungsseiten angelegt." #: templates/reversion/recover_form.html:14 #: templates/reversion/recover_list.html:6 #: templates/reversion/revision_form.html:14 msgid "Home" msgstr "Start" #: templates/reversion/recover_form.html:17 #, python-format msgid "Recover deleted %(verbose_name)s" msgstr "Gelöschte %(verbose_name)s wiederherstellen" #: templates/reversion/recover_form.html:18 #, python-format msgid "Recover %(name)s" msgstr "%(name)s wiederherstellen" #: templates/reversion/recover_form.html:24 msgid "Press the save button below to recover this version of the object." msgstr "Sichern Sie, um diese Version des Objektes wiederherzustellen." #: templates/reversion/recover_list.html:15 msgid "" "Choose a date from the list below to recover a deleted version of an object." msgstr "" "Wählen Sie einen Zeitpunk aus der untenstehenden Liste, um eine gelöschte " "Version des Objektes wiederherzustellen." #: templates/reversion/recover_list.html:35 msgid "There are no deleted objects to recover." msgstr "Es sind keine gelöschten Objekte zur Wiederherstellung vorhanden." #: templates/reversion/revision_form.html:18 msgid "History" msgstr "Geschichte" #: templates/reversion/revision_form.html:19 #, python-format msgid "Revert %(verbose_name)s" msgstr "%(verbose_name)s zurĂĽcksetzen" #: templates/reversion/revision_form.html:32 msgid "Press the save button below to revert to this version of the object." msgstr "Sichern Sie, um das Objekt zu dieser Version zurĂĽckzusetzen." django-reversion-2.0.13/reversion/locale/es/000077500000000000000000000000001323160775000207375ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/es/LC_MESSAGES/000077500000000000000000000000001323160775000225245ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/es/LC_MESSAGES/django.mo000066400000000000000000000047121323160775000243270ustar00rootroot00000000000000ޕԌL QV¨ °şÔÜáBňD5z‹¤´3ĚP(QXzÓŘ ŕí“ňW†[Ţ : EP lv}BŽCŃ(FX:rU­% r) ś ¤ Ż       Choose a date from the list below to recover a deleted version of an object.Choose a date from the list below to revert to a previous version of this object.CommentDate/timeDeleted %(verbose_name)s.HistoryHomeInitial version.Press the save button below to recover this version of the object.Press the save button below to revert to this version of the object.Recover %(name)sRecover deleted %(name)sRevert %(name)sRevert %(verbose_name)sReverted to previous version, saved on %(datetime)sThe %(model)s "%(name)s" was reverted successfully. You may edit it again below.There are no deleted objects to recover.This object doesn't have a change history. It probably wasn't added via this admin site.Usercommentdate createduserProject-Id-Version: PACKAGE VERSION Report-Msgid-Bugs-To: POT-Creation-Date: 2013-08-31 15:49-0500 PO-Revision-Date: 2013-08-31 16:22-0500 Last-Translator: Alexander Ayasca Esquives Language-Team: LANGUAGE Language: es MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); Escoja una fecha de la lista siguiente para recuperar una versiĂłn eliminada del objetoEscoja una fecha de la lista siguiente para revertir a una versiĂłn anterior de este objetoComentarioFecha/Hora%(verbose_name)s eliminadosHistorialInicioVersiĂłn inicialPresione el botĂłn guardar para recuperar esta versiĂłn del objetoPresione el botĂłn guardar para revertir a esta versiĂłn del objetoRecuperar %(name)sRecuperar %(name)s eliminadosRevertir %(name)sRevertir %(verbose_name)sRevertido a una versiĂłn anterior, grabada el %(datetime)sEl %(model)s "%(name)s" fue revertido satisfactoriamente. Puede editarlo nuevamente No hay objetos eliminados a recuperarEste objeto no tiene un historial de cambios. Probablemente no fue añadido por medio del sitio de administraciĂłnUsuariocomentariofecha de creaciĂłnusuariodjango-reversion-2.0.13/reversion/locale/es/LC_MESSAGES/django.po000066400000000000000000000072671323160775000243420ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , 2013. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2013-08-31 15:49-0500\n" "PO-Revision-Date: 2013-08-31 16:22-0500\n" "Last-Translator: Alexander Ayasca Esquives \n" "Language-Team: LANGUAGE \n" "Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #: admin.py:144 msgid "Initial version." msgstr "VersiĂłn inicial" #: admin.py:166 #, python-format msgid "Deleted %(verbose_name)s." msgstr "%(verbose_name)s eliminados" #: admin.py:189 templates/reversion/change_list.html:7 #: templates/reversion/recover_form.html:11 #: templates/reversion/recover_list.html:11 #, python-format msgid "Recover deleted %(name)s" msgstr "Recuperar %(name)s eliminados" #: admin.py:304 #, python-format msgid "Reverted to previous version, saved on %(datetime)s" msgstr "Revertido a una versiĂłn anterior, grabada el %(datetime)s" #: admin.py:306 #, python-format msgid "" "The %(model)s \"%(name)s\" was reverted successfully. You may edit it again " "below." msgstr "El %(model)s \"%(name)s\" fue revertido satisfactoriamente. Puede editarlo nuevamente " #: admin.py:392 #, python-format msgid "Recover %(name)s" msgstr "Recuperar %(name)s" #: admin.py:406 #, python-format msgid "Revert %(name)s" msgstr "Revertir %(name)s" #: models.py:59 msgid "date created" msgstr "fecha de creaciĂłn" #: models.py:65 msgid "user" msgstr "usuario" #: models.py:69 msgid "comment" msgstr "comentario" #: templates/reversion/object_history.html:8 msgid "" "Choose a date from the list below to revert to a previous version of this " "object." msgstr "Escoja una fecha de la lista siguiente para revertir a una versiĂłn anterior de este objeto" #: templates/reversion/object_history.html:15 #: templates/reversion/recover_list.html:24 msgid "Date/time" msgstr "Fecha/Hora" #: templates/reversion/object_history.html:16 msgid "User" msgstr "Usuario" #: templates/reversion/object_history.html:17 msgid "Comment" msgstr "Comentario" #: templates/reversion/object_history.html:36 msgid "" "This object doesn't have a change history. It probably wasn't added via this " "admin site." msgstr "Este objeto no tiene un historial de cambios. Probablemente no fue añadido por medio del sitio de administraciĂłn" #: templates/reversion/recover_form.html:8 #: templates/reversion/recover_list.html:8 #: templates/reversion/revision_form.html:8 msgid "Home" msgstr "Inicio" #: templates/reversion/recover_form.html:18 msgid "Press the save button below to recover this version of the object." msgstr "Presione el botĂłn guardar para recuperar esta versiĂłn del objeto" #: templates/reversion/recover_list.html:18 msgid "" "Choose a date from the list below to recover a deleted version of an object." msgstr "Escoja una fecha de la lista siguiente para recuperar una versiĂłn eliminada del objeto" #: templates/reversion/recover_list.html:38 msgid "There are no deleted objects to recover." msgstr "No hay objetos eliminados a recuperar" #: templates/reversion/revision_form.html:12 msgid "History" msgstr "Historial" #: templates/reversion/revision_form.html:13 #, python-format msgid "Revert %(verbose_name)s" msgstr "Revertir %(verbose_name)s" #: templates/reversion/revision_form.html:26 msgid "Press the save button below to revert to this version of the object." msgstr "Presione el botĂłn guardar para revertir a esta versiĂłn del objeto" django-reversion-2.0.13/reversion/locale/es_AR/000077500000000000000000000000001323160775000213215ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/es_AR/LC_MESSAGES/000077500000000000000000000000001323160775000231065ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/es_AR/LC_MESSAGES/django.mo000066400000000000000000000047131323160775000247120ustar00rootroot00000000000000ޕԌL QV¨ °şÔÜáBňD5z‹¤´3ĚP(QXzÓŘ ŕípň]c`Á " -8 T^eCwD»1C;]]™)÷{! ť Ą ° Ă      Choose a date from the list below to recover a deleted version of an object.Choose a date from the list below to revert to a previous version of this object.CommentDate/timeDeleted %(verbose_name)s.HistoryHomeInitial version.Press the save button below to recover this version of the object.Press the save button below to revert to this version of the object.Recover %(name)sRecover deleted %(name)sRevert %(name)sRevert %(verbose_name)sReverted to previous version, saved on %(datetime)sThe %(model)s "%(name)s" was reverted successfully. You may edit it again below.There are no deleted objects to recover.This object doesn't have a change history. It probably wasn't added via this admin site.Usercommentdate createduserProject-Id-Version: Report-Msgid-Bugs-To: POT-Creation-Date: 2015-10-11 19:10-0300 PO-Revision-Date: 2015-10-11 19:12-0300 Last-Translator: Gonzalo Bustos Language-Team: Spanish (Argentina) Language: es_AR MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1); X-Generator: Poedit 1.6.10 Elija una fecha del listado a continuaciĂłn para restaurar una versiĂłn eliminada del objeto.Elija una fecha del listado a continuaciĂłn para revertir a una versiĂłn anterior de este objetoComentarioFecha/hora%(verbose_name)s eliminadosHistorialInicioVersiĂłn inicial.Presione el botĂłn guardar para restaurar esta versiĂłn del objeto.Presione el botĂłn guardar para revertir a esta versiĂłn del objeto.Restaurar %(name)sRestaurar %(name)s eliminadosRevertir %(name)sRevertir %(verbose_name)sRevertido a una versiĂłn anterior, guardada el %(datetime)sEl %(model)s "%(name)s" fue revertido con Ă©xito. Puede editarlo nuevamente a continuaciĂłn.No hay objetos eliminados para restaurar.Este objeto no tiene un historial de cambios. Es probable que no haya sido agregado a travĂ©s del sitio de administraciĂłn.Usuariocomentariofecha de creaciĂłnusuariodjango-reversion-2.0.13/reversion/locale/es_AR/LC_MESSAGES/django.po000066400000000000000000000072471323160775000247220ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Gonzalo Bustos, 2015. # msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2015-10-11 19:10-0300\n" "PO-Revision-Date: 2015-10-11 19:12-0300\n" "Last-Translator: Gonzalo Bustos\n" "Language-Team: Spanish (Argentina)\n" "Language: es_AR\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" "X-Generator: Poedit 1.6.10\n" #: admin.py:144 msgid "Initial version." msgstr "VersiĂłn inicial." #: admin.py:166 #, python-format msgid "Deleted %(verbose_name)s." msgstr "%(verbose_name)s eliminados" #: admin.py:189 templates/reversion/change_list.html:7 #: templates/reversion/recover_form.html:11 #: templates/reversion/recover_list.html:11 #, python-format msgid "Recover deleted %(name)s" msgstr "Restaurar %(name)s eliminados" #: admin.py:304 #, python-format msgid "Reverted to previous version, saved on %(datetime)s" msgstr "Revertido a una versiĂłn anterior, guardada el %(datetime)s" #: admin.py:306 #, python-format msgid "" "The %(model)s \"%(name)s\" was reverted successfully. You may edit it again " "below." msgstr "" "El %(model)s \"%(name)s\" fue revertido con Ă©xito. Puede editarlo " "nuevamente a continuaciĂłn." #: admin.py:392 #, python-format msgid "Recover %(name)s" msgstr "Restaurar %(name)s" #: admin.py:406 #, python-format msgid "Revert %(name)s" msgstr "Revertir %(name)s" #: models.py:59 msgid "date created" msgstr "fecha de creaciĂłn" #: models.py:65 msgid "user" msgstr "usuario" #: models.py:69 msgid "comment" msgstr "comentario" #: templates/reversion/object_history.html:8 msgid "" "Choose a date from the list below to revert to a previous version of this " "object." msgstr "" "Elija una fecha del listado a continuaciĂłn para revertir a una versiĂłn " "anterior de este objeto" #: templates/reversion/object_history.html:15 #: templates/reversion/recover_list.html:24 msgid "Date/time" msgstr "Fecha/hora" #: templates/reversion/object_history.html:16 msgid "User" msgstr "Usuario" #: templates/reversion/object_history.html:17 msgid "Comment" msgstr "Comentario" #: templates/reversion/object_history.html:36 msgid "" "This object doesn't have a change history. It probably wasn't added via this " "admin site." msgstr "" "Este objeto no tiene un historial de cambios. Es probable que no haya sido " "agregado a travĂ©s del sitio de administraciĂłn." #: templates/reversion/recover_form.html:8 #: templates/reversion/recover_list.html:8 #: templates/reversion/revision_form.html:8 msgid "Home" msgstr "Inicio" #: templates/reversion/recover_form.html:18 msgid "Press the save button below to recover this version of the object." msgstr "Presione el botĂłn guardar para restaurar esta versiĂłn del objeto." #: templates/reversion/recover_list.html:18 msgid "" "Choose a date from the list below to recover a deleted version of an object." msgstr "" "Elija una fecha del listado a continuaciĂłn para restaurar una versiĂłn " "eliminada del objeto." #: templates/reversion/recover_list.html:38 msgid "There are no deleted objects to recover." msgstr "No hay objetos eliminados para restaurar." #: templates/reversion/revision_form.html:12 msgid "History" msgstr "Historial" #: templates/reversion/revision_form.html:13 #, python-format msgid "Revert %(verbose_name)s" msgstr "Revertir %(verbose_name)s" #: templates/reversion/revision_form.html:26 msgid "Press the save button below to revert to this version of the object." msgstr "Presione el botĂłn guardar para revertir a esta versiĂłn del objeto." django-reversion-2.0.13/reversion/locale/fr/000077500000000000000000000000001323160775000207375ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/fr/LC_MESSAGES/000077500000000000000000000000001323160775000225245ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/fr/LC_MESSAGES/django.mo000066400000000000000000000050261323160775000243260ustar00rootroot00000000000000Ţ•ÄlŕLáQ.€ ˘ĽÄÉBÚDbsŚś3´Pč(9Xb»~ŔX?i   % ALT`flÇ4Ii|B—fÚ8A Źz     Choose a date from the list below to recover a deleted version of an object.Choose a date from the list below to revert to a previous version of this object.CommentDATETIME_FORMATDate/timeDeleted %(verbose_name)s.HistoryHomeInitial version.Press the save button below to recover this version of the object.Press the save button below to revert to this version of the object.Recover %(name)sRecover deleted %(name)sRevert %(name)sRevert %(verbose_name)sReverted to previous version, saved on %(datetime)sThe %(model)s "%(name)s" was reverted successfully. You may edit it again below.There are no deleted objects to recover.This object doesn't have a change history. It probably wasn't added via this admin site.UserProject-Id-Version: PACKAGE VERSION Report-Msgid-Bugs-To: POT-Creation-Date: 2010-10-01 20:56-0400 PO-Revision-Date: 2011-09-21 16:31-0400 Last-Translator: Etienne Desautels Language-Team: LANGUAGE Language: fr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=n>1; Choisissez une date dans la liste ci-dessous afin de rĂ©cupĂ©rer un Ă©lĂ©ment supprimĂ©.Choisissez une date dans la liste ci-dessous afin de restaurer une version prĂ©cĂ©dente de cet Ă©lĂ©ment.Commentairej F Y H:i:sDate/heureSupprimĂ© %(verbose_name)s.HistoriqueAccueilVersion initiale.Cliquez sur le bouton Enregistrer ci-dessous afin de rĂ©cupĂ©rer cet Ă©lĂ©ment.Cliquez sur le bouton Enregistrer ci-dessous pour restaurer cette version de l’élĂ©ment.RĂ©cupĂ©rer %(name)sRĂ©cupĂ©rer %(name)s supprimĂ©sRestaurer %(name)sRestaurer %(verbose_name)sRestaurĂ© depuis une version prĂ©cĂ©dente, sauvĂ©e le %(datetime)sL’élĂ©ment %(model)s "%(name)s" a Ă©tĂ© restaurĂ© avec succès. Vous pouvez l’éditer Ă  nouveau.Il n’y a pas d’élĂ©ments supprimĂ©s Ă  rĂ©cupĂ©rer.Cet Ă©lĂ©ment ne possède pas d’historique de modifications. Il n’a probablement pas Ă©tĂ© ajoutĂ© Ă  partir de ce site d’administration.Utilisateurdjango-reversion-2.0.13/reversion/locale/fr/LC_MESSAGES/django.po000066400000000000000000000075111323160775000243320ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Simon Charette , 2010. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2010-10-01 20:56-0400\n" "PO-Revision-Date: 2011-09-21 16:31-0400\n" "Last-Translator: Etienne Desautels \n" "Language-Team: LANGUAGE \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=n>1;\n" #: admin.py:143 templates/reversion/change_list.html:7 #: templates/reversion/recover_form.html:10 #: templates/reversion/recover_list.html:10 #, python-format msgid "Recover deleted %(name)s" msgstr "RĂ©cupĂ©rer %(name)s supprimĂ©s" #: admin.py:123 #, python-format msgid "Deleted %(verbose_name)s." msgstr "SupprimĂ© %(verbose_name)s." #: admin.py:252 #, python-format msgid "Reverted to previous version, saved on %(datetime)s" msgstr "RestaurĂ© depuis une version prĂ©cĂ©dente, sauvĂ©e le %(datetime)s" #: admin.py:254 #, python-format msgid "" "The %(model)s \"%(name)s\" was reverted successfully. You may edit it again " "below." msgstr "" "L’élĂ©ment %(model)s \"%(name)s\" a Ă©tĂ© restaurĂ© avec succès. Vous pouvez " "l’éditer Ă  nouveau." #: admin.py:337 #, python-format msgid "Recover %(name)s" msgstr "RĂ©cupĂ©rer %(name)s" #: admin.py:349 #, python-format msgid "Revert %(name)s" msgstr "Restaurer %(name)s" #: admin.py:111 msgid "Initial version." msgstr "Version initiale." #: templates/reversion/object_history.html:8 msgid "" "Choose a date from the list below to revert to a previous version of this " "object." msgstr "Choisissez une date dans la liste ci-dessous afin de restaurer " "une version prĂ©cĂ©dente de cet Ă©lĂ©ment." #: templates/reversion/object_history.html:15 #: templates/reversion/recover_list.html:23 msgid "Date/time" msgstr "Date/heure" #: templates/reversion/object_history.html:16 msgid "User" msgstr "Utilisateur" #: templates/reversion/object_history.html:17 msgid "Comment" msgstr "Commentaire" #: admin.py:252 templates/reversion/object_history.html:23 #: templates/reversion/recover_list.html:30 msgid "DATETIME_FORMAT" msgstr "j F Y H:i:s" #: templates/reversion/object_history.html:36 msgid "" "This object doesn't have a change history. It probably wasn't added via this " "admin site." msgstr "" "Cet Ă©lĂ©ment ne possède pas d’historique de modifications. Il n’a " "probablement pas Ă©tĂ© ajoutĂ© Ă  partir de ce site d’administration." #: templates/reversion/recover_form.html:7 #: templates/reversion/recover_list.html:7 #: templates/reversion/revision_form.html:7 msgid "Home" msgstr "Accueil" #: templates/reversion/recover_form.html:17 msgid "Press the save button below to recover this version of the object." msgstr "Cliquez sur le bouton Enregistrer ci-dessous afin de " "rĂ©cupĂ©rer cet Ă©lĂ©ment." #: templates/reversion/recover_list.html:17 msgid "" "Choose a date from the list below to recover a deleted version of an object." msgstr "Choisissez une date dans la liste ci-dessous afin de rĂ©cupĂ©rer un " "Ă©lĂ©ment supprimĂ©." #: templates/reversion/recover_list.html:37 msgid "There are no deleted objects to recover." msgstr "Il n’y a pas d’élĂ©ments supprimĂ©s Ă  rĂ©cupĂ©rer." #: templates/reversion/revision_form.html:11 msgid "History" msgstr "Historique" #: templates/reversion/revision_form.html:12 #, python-format msgid "Revert %(verbose_name)s" msgstr "Restaurer %(verbose_name)s" #: templates/reversion/revision_form.html:25 msgid "Press the save button below to revert to this version of the object." msgstr "Cliquez sur le bouton Enregistrer ci-dessous pour " "restaurer cette version de l’élĂ©ment." django-reversion-2.0.13/reversion/locale/he/000077500000000000000000000000001323160775000207245ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/he/LC_MESSAGES/000077500000000000000000000000001323160775000225115ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/he/LC_MESSAGES/django.mo000066400000000000000000000047421323160775000243170ustar00rootroot00000000000000Ţ•Älŕ áLîQ;Ť• ĄŻ·BĽD˙DU nŹź3·Pë(<Xeľ5Ăů] tkŕéř k$kü &1Xl<fĹ3, v` ×     Add %(name)sChoose a date from the list below to recover a deleted version of an object.Choose a date from the list below to revert to a previous version of this object.CommentDATETIME_FORMATDate/timeHistoryHomePress the save button below to recover this version of the object.Press the save button below to revert to this version of the object.Recover %(name)sRecover deleted %(name)sRecover deleted %(verbose_name)sRevert %(name)sRevert %(verbose_name)sReverted to previous version, saved on %(datetime)sThe %(model)s "%(name)s" was reverted successfully. You may edit it again below.There are no deleted objects to recover.This object doesn't have a change history. It probably wasn't added via this admin site.UserProject-Id-Version: PACKAGE VERSION Report-Msgid-Bugs-To: POT-Creation-Date: 2009-12-10 10:27+0200 PO-Revision-Date: 2009-12-10 10:45+0200 Last-Translator: FULL NAME Language-Team: LANGUAGE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit הוספת %(name)s× × ×ś×‘×—×•×¨ ת×ריך מתחת כדי ל×חזר גרסה מחוקה של ×ובייק×× × ×ś×‘×—×•×¨ ת×ריך מהרשימה להלן כדי לשחזר לגרסה קודמת של ××•×‘×™×™×§× ×–×”.הערהd.m.‏Y H:i:sת×ריך/שעההיס×וריהר××©×™× × ×ś×ś×—×•×Ą על לחצן השמירה מתחת כדי ל×חזר לגרסה זו של ×”×ובייק×× × ×ś×ś×—×•×Ą על לחצן השמירה מתחת כדי לשחזר לגרסה זו של ×”×ובייק××חזור %(name)sשחזור %(name)s שנמחקו×חזור %(verbose_name)s שנמחקשחזור %(name)sשחזור %(verbose_name)sשוחזר לגרסה קודמת, נשמרה ב-%(datetime)sשחזור %(model)s "%(name)s" לגרסה קודמת הצליח. ניתן לערוך שוב מתחת.×ין ×ובייק×ים מחוקים ל×חזורל××•×‘×™×™×§× ×–×” ×ין היס×וריית שינוי. כנר××” ×ś× ×”×Ş×•×•×ˇ×Ł דרך ממשק הניהול.משתמשdjango-reversion-2.0.13/reversion/locale/he/LC_MESSAGES/django.po000066400000000000000000000074101323160775000243150ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2009-12-10 10:27+0200\n" "PO-Revision-Date: 2009-12-10 10:45+0200\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: admin.py:112 templates/reversion/change_list.html:7 #: templates/reversion/recover_list.html:10 #, python-format msgid "Recover deleted %(name)s" msgstr "שחזור %(name)s שנמחקו" #: admin.py:158 #, python-format msgid "Reverted to previous version, saved on %(datetime)s" msgstr "שוחזר לגרסה קודמת, נשמרה ב-%(datetime)s" #: admin.py:160 #, python-format msgid "" "The %(model)s \"%(name)s\" was reverted successfully. You may edit it again " "below." msgstr "" "שחזור %(model)s \"%(name)s\" לגרסה קודמת הצליח. ניתן לערוך שוב " "מתחת." #: admin.py:259 #, python-format msgid "Recover %(name)s" msgstr "×חזור %(name)s" #: admin.py:269 #, python-format msgid "Revert %(name)s" msgstr "שחזור %(name)s" #: templates/reversion/change_list.html:9 #, python-format msgid "Add %(name)s" msgstr "הוספת %(name)s" #: templates/reversion/object_history.html:8 msgid "" "Choose a date from the list below to revert to a previous version of this " "object." msgstr "" "× × ×ś×‘×—×•×¨ ת×ריך מהרשימה להלן כדי לשחזר לגרסה קודמת של " "××•×‘×™×™×§× ×–×”." #: templates/reversion/object_history.html:15 #: templates/reversion/recover_list.html:23 msgid "Date/time" msgstr "ת×ריך/שעה" #: templates/reversion/object_history.html:16 msgid "User" msgstr "משתמש" #: templates/reversion/object_history.html:17 msgid "Comment" msgstr "הערה" #: templates/reversion/object_history.html:23 #: templates/reversion/recover_list.html:30 msgid "DATETIME_FORMAT" msgstr "d.m.‏Y H:i:s" #: templates/reversion/object_history.html:31 msgid "" "This object doesn't have a change history. It probably wasn't added via this " "admin site." msgstr "" "ל××•×‘×™×™×§× ×–×” ×ין היס×וריית שינוי. כנר××” ×ś× ×”×Ş×•×•×ˇ×Ł דרך " "ממשק הניהול." #: templates/reversion/recover_form.html:14 #: templates/reversion/recover_list.html:7 #: templates/reversion/revision_form.html:14 msgid "Home" msgstr "ר×שי" #: templates/reversion/recover_form.html:17 #, python-format msgid "Recover deleted %(verbose_name)s" msgstr "×חזור %(verbose_name)s שנמחק" #: templates/reversion/recover_form.html:24 msgid "Press the save button below to recover this version of the object." msgstr "× × ×ś×ś×—×•×Ą על לחצן השמירה מתחת כדי ל×חזר לגרסה זו של ×”×ובייק×" #: templates/reversion/recover_list.html:17 msgid "" "Choose a date from the list below to recover a deleted version of an object." msgstr "" "× × ×ś×‘×—×•×¨ ת×ריך מתחת כדי ל×חזר גרסה מחוקה של ×ובייק×" #: templates/reversion/recover_list.html:37 msgid "There are no deleted objects to recover." msgstr "×ין ×ובייק×ים מחוקים ל×חזור" #: templates/reversion/revision_form.html:18 msgid "History" msgstr "היס×וריה" #: templates/reversion/revision_form.html:19 #, python-format msgid "Revert %(verbose_name)s" msgstr "שחזור %(verbose_name)s" #: templates/reversion/revision_form.html:32 msgid "Press the save button below to revert to this version of the object." msgstr "× × ×ś×ś×—×•×Ą על לחצן השמירה מתחת כדי לשחזר לגרסה זו של ×”×ובייק×" django-reversion-2.0.13/reversion/locale/it/000077500000000000000000000000001323160775000207445ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/it/LC_MESSAGES/000077500000000000000000000000001323160775000225315ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/it/LC_MESSAGES/django.mo000066400000000000000000000045331323160775000243350ustar00rootroot00000000000000Ţ•Älŕ áLîQ;Ť• ĄŻ·BĽD˙DU nŹź3·Pë(<Xeľ<Ă_`rÓ Üçđ÷MüMJŞ$Çěý9aP-˛sŕT     Add %(name)sChoose a date from the list below to recover a deleted version of an object.Choose a date from the list below to revert to a previous version of this object.CommentDATETIME_FORMATDate/timeHistoryHomePress the save button below to recover this version of the object.Press the save button below to revert to this version of the object.Recover %(name)sRecover deleted %(name)sRecover deleted %(verbose_name)sRevert %(name)sRevert %(verbose_name)sReverted to previous version, saved on %(datetime)sThe %(model)s "%(name)s" was reverted successfully. You may edit it again below.There are no deleted objects to recover.This object doesn't have a change history. It probably wasn't added via this admin site.UserProject-Id-Version: PACKAGE VERSION Report-Msgid-Bugs-To: POT-Creation-Date: 2009-08-29 13:04+0200 PO-Revision-Date: 2009-08-29 13:44+0100 Last-Translator: Marco Beri Language-Team: LANGUAGE MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Aggiungi %(name)sScegli una data dall'elenco qui sotto per recuperare una versione cancellata di questo oggetto.Scegli una data dall'elenco qui sotto per ritornare a una precedente versione di questo oggetto.Commentod/m/Y, G:iData/oraStoriaHomePremi il pulsante Salva in basso per recuperare questa versione dell'oggetto.Premi il pulsante Salva in basso per ritornare a questa versione dell'oggettoRecupera %(name)sRecupera %(name)s cancellatiRecupera %(verbose_name)s cancellatoRitorna %(name)sRitorna %(verbose_name)sRitorna alla precedente versione, salvata il %(datetime)s%(model)s "%(name)s" è alla versione precedente. Puoi effettuare nuove modifiche se lo desideri.Non ci sono oggetti cancellati da recuperare.Questo oggetto non ha una storia di modifiche. Probabilmente non è stato aggiunto attraverso questo sito di Admin.Utentedjango-reversion-2.0.13/reversion/locale/it/LC_MESSAGES/django.po000066400000000000000000000073541323160775000243440ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2009-08-29 13:04+0200\n" "PO-Revision-Date: 2009-08-29 13:44+0100\n" "Last-Translator: Marco Beri \n" "Language-Team: LANGUAGE \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: .\admin.py:128 #: .\templates\reversion\change_list.html.py:7 #: .\templates\reversion\recover_list.html.py:10 msgid "Recover deleted %(name)s" msgstr "Recupera %(name)s cancellati" #: .\admin.py:173 #, python-format msgid "Reverted to previous version, saved on %(datetime)s" msgstr "Ritorna alla precedente versione, salvata il %(datetime)s" #: .\admin.py:175 #, python-format msgid "The %(model)s \"%(name)s\" was reverted successfully. You may edit it again below." msgstr "%(model)s \"%(name)s\" è alla versione precedente. Puoi effettuare nuove modifiche se lo desideri." #: .\admin.py:271 #, python-format msgid "Recover %(name)s" msgstr "Recupera %(name)s" #: .\admin.py:281 #, python-format msgid "Revert %(name)s" msgstr "Ritorna %(name)s" #: .\templates\reversion\change_list.html.py:9 #, python-format msgid "Add %(name)s" msgstr "Aggiungi %(name)s" #: .\templates\reversion\object_history.html.py:8 msgid "Choose a date from the list below to revert to a previous version of this object." msgstr "Scegli una data dall'elenco qui sotto per ritornare a una precedente versione di questo oggetto." #: .\templates\reversion\object_history.html.py:15 #: .\templates\reversion\recover_list.html.py:23 msgid "Date/time" msgstr "Data/ora" #: .\templates\reversion\object_history.html.py:16 msgid "User" msgstr "Utente" #: .\templates\reversion\object_history.html.py:17 msgid "Comment" msgstr "Commento" #: .\templates\reversion\object_history.html.py:23 #: .\templates\reversion\recover_list.html.py:30 msgid "DATETIME_FORMAT" msgstr "d/m/Y, G:i" #: .\templates\reversion\object_history.html.py:31 msgid "This object doesn't have a change history. It probably wasn't added via this admin site." msgstr "Questo oggetto non ha una storia di modifiche. Probabilmente non è stato aggiunto attraverso questo sito di Admin." #: .\templates\reversion\recover_form.html.py:14 #: .\templates\reversion\recover_list.html.py:7 #: .\templates\reversion\revision_form.html.py:14 msgid "Home" msgstr "Home" #: .\templates\reversion\recover_form.html.py:17 #, python-format msgid "Recover deleted %(verbose_name)s" msgstr "Recupera %(verbose_name)s cancellato" #: .\templates\reversion\recover_form.html.py:24 msgid "Press the save button below to recover this version of the object." msgstr "Premi il pulsante Salva in basso per recuperare questa versione dell'oggetto." #: .\templates\reversion\recover_list.html.py:17 msgid "Choose a date from the list below to recover a deleted version of an object." msgstr "Scegli una data dall'elenco qui sotto per recuperare una versione cancellata di questo oggetto." #: .\templates\reversion\recover_list.html.py:37 msgid "There are no deleted objects to recover." msgstr "Non ci sono oggetti cancellati da recuperare." #: .\templates\reversion\revision_form.html.py:18 msgid "History" msgstr "Storia" #: .\templates\reversion\revision_form.html.py:19 #, python-format msgid "Revert %(verbose_name)s" msgstr "Ritorna %(verbose_name)s" #: .\templates\reversion\revision_form.html.py:32 msgid "Press the save button below to revert to this version of the object." msgstr "Premi il pulsante Salva in basso per ritornare a questa versione dell'oggetto" #~ msgid "Recover %s" #~ msgstr "Recupera %s" django-reversion-2.0.13/reversion/locale/nb/000077500000000000000000000000001323160775000207275ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/nb/LC_MESSAGES/000077500000000000000000000000001323160775000225145ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/nb/LC_MESSAGES/django.mo000066400000000000000000000047121323160775000243170ustar00rootroot00000000000000Ţ•ÄlŕLáQ.€ ˘ĽÄÉBÚDbsŚś3´Pč(9Xb»żŔU€_Ö 6 @KTnw|QŚQŢ0Ecy:—KŇ/ tN Ă     Choose a date from the list below to recover a deleted version of an object.Choose a date from the list below to revert to a previous version of this object.CommentDATETIME_FORMATDate/timeDeleted %(verbose_name)s.HistoryHomeInitial version.Press the save button below to recover this version of the object.Press the save button below to revert to this version of the object.Recover %(name)sRecover deleted %(name)sRevert %(name)sRevert %(verbose_name)sReverted to previous version, saved on %(datetime)sThe %(model)s "%(name)s" was reverted successfully. You may edit it again below.There are no deleted objects to recover.This object doesn't have a change history. It probably wasn't added via this admin site.UserProject-Id-Version: django-reversion Report-Msgid-Bugs-To: POT-Creation-Date: 2011-10-17 09:34+0200 PO-Revision-Date: 2011-10-17 10:17+0100 Last-Translator: Sindre Sorhus Language-Team: Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1) X-Poedit-Language: Norwegian Bokmal X-Poedit-Country: NORWAY X-Poedit-SourceCharset: utf-8 Velg en dato fra listen nedenfor for ĂĄ gjenopprette en slettet versjon av et objekt.Velg en dato fra listen nedenfor for ĂĄ gĂĄ tilbake til en tidligere versjon av dette objektet.Kommentarj. F Y H:iDato/tidSlettet %(verbose_name)s.HistorieHjemInitial versjonTrykk pĂĄ lagre-knappen nedenfor for ĂĄ gjenopprette denne versjonen av objektet.Trykk pĂĄ lagre-knappen under for ĂĄ gĂĄ tilbake til denne versjonen av objektet.Gjenopprett %(name)sGjenopprett slettede %(name)sTilbakestill %(name)sTilbakestill %(verbose_name)sGjenopprettet til forrige versjon, lagret den %(datetime)s%(model)s "%(name)s" ble gjenopprettet. Du kan redigere den igjen nedenfor.Finner ingen slettede objekter ĂĄ gjenopprette.Dette objektet har ingen endringshistorie. Objektet er sannsynligvis ikke blitt lagt inn via dette admin nettstedet.Brukerdjango-reversion-2.0.13/reversion/locale/nb/LC_MESSAGES/django.po000066400000000000000000000073031323160775000243210ustar00rootroot00000000000000# Norwegian translation for django-reversion # This file is distributed under the same license as the django-reversion package. # Sindre Sorhus , 2011. # msgid "" msgstr "" "Project-Id-Version: django-reversion\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2011-10-17 09:34+0200\n" "PO-Revision-Date: 2011-10-17 10:17+0100\n" "Last-Translator: Sindre Sorhus \n" "Language-Team: \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" "X-Poedit-Language: Norwegian Bokmal\n" "X-Poedit-Country: NORWAY\n" "X-Poedit-SourceCharset: utf-8\n" #: admin.py:111 msgid "Initial version." msgstr "Initial versjon" #: admin.py:125 #, python-format msgid "Deleted %(verbose_name)s." msgstr "Slettet %(verbose_name)s." #: admin.py:143 #: templates/reversion/change_list.html:7 #: templates/reversion/recover_form.html:10 #: templates/reversion/recover_list.html:10 #, python-format msgid "Recover deleted %(name)s" msgstr "Gjenopprett slettede %(name)s" #: admin.py:252 #, python-format msgid "Reverted to previous version, saved on %(datetime)s" msgstr "Gjenopprettet til forrige versjon, lagret den %(datetime)s" #: admin.py:252 #: templates/reversion/object_history.html:23 #: templates/reversion/recover_list.html:30 msgid "DATETIME_FORMAT" msgstr "j. F Y H:i" #: admin.py:254 #, python-format msgid "The %(model)s \"%(name)s\" was reverted successfully. You may edit it again below." msgstr "%(model)s \"%(name)s\" ble gjenopprettet. Du kan redigere den igjen nedenfor." #: admin.py:337 #, python-format msgid "Recover %(name)s" msgstr "Gjenopprett %(name)s" #: admin.py:349 #, python-format msgid "Revert %(name)s" msgstr "Tilbakestill %(name)s" #: templates/reversion/object_history.html:8 msgid "Choose a date from the list below to revert to a previous version of this object." msgstr "Velg en dato fra listen nedenfor for ĂĄ gĂĄ tilbake til en tidligere versjon av dette objektet." #: templates/reversion/object_history.html:15 #: templates/reversion/recover_list.html:23 msgid "Date/time" msgstr "Dato/tid" #: templates/reversion/object_history.html:16 msgid "User" msgstr "Bruker" #: templates/reversion/object_history.html:17 msgid "Comment" msgstr "Kommentar" #: templates/reversion/object_history.html:36 msgid "This object doesn't have a change history. It probably wasn't added via this admin site." msgstr "Dette objektet har ingen endringshistorie. Objektet er sannsynligvis ikke blitt lagt inn via dette admin nettstedet." #: templates/reversion/recover_form.html:7 #: templates/reversion/recover_list.html:7 #: templates/reversion/revision_form.html:7 msgid "Home" msgstr "Hjem" #: templates/reversion/recover_form.html:17 msgid "Press the save button below to recover this version of the object." msgstr "Trykk pĂĄ lagre-knappen nedenfor for ĂĄ gjenopprette denne versjonen av objektet." #: templates/reversion/recover_list.html:17 msgid "Choose a date from the list below to recover a deleted version of an object." msgstr "Velg en dato fra listen nedenfor for ĂĄ gjenopprette en slettet versjon av et objekt." #: templates/reversion/recover_list.html:37 msgid "There are no deleted objects to recover." msgstr "Finner ingen slettede objekter ĂĄ gjenopprette." #: templates/reversion/revision_form.html:11 msgid "History" msgstr "Historie" #: templates/reversion/revision_form.html:12 #, python-format msgid "Revert %(verbose_name)s" msgstr "Tilbakestill %(verbose_name)s" #: templates/reversion/revision_form.html:25 msgid "Press the save button below to revert to this version of the object." msgstr "Trykk pĂĄ lagre-knappen under for ĂĄ gĂĄ tilbake til denne versjonen av objektet." django-reversion-2.0.13/reversion/locale/nl/000077500000000000000000000000001323160775000207415ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/nl/LC_MESSAGES/000077500000000000000000000000001323160775000225265ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/nl/LC_MESSAGES/django.mo000066400000000000000000000046221323160775000243310ustar00rootroot00000000000000Ţ•Ě|đLńQ> ˘ĽÄBŐD]n‡—3ŻPă(4X]¶» ĂĐyŐXOH¨ ńý  ,9FHJŹÚë0>Ro=Â` a k w     Choose a date from the list below to recover a deleted version of an object.Choose a date from the list below to revert to a previous version of this object.CommentDate/timeDeleted %(verbose_name)s.HistoryInitial version.Press the save button below to recover this version of the object.Press the save button below to revert to this version of the object.Recover %(name)sRecover deleted %(name)sRevert %(name)sRevert %(verbose_name)sReverted to previous version, saved on %(datetime)sThe %(model)s "%(name)s" was reverted successfully. You may edit it again below.There are no deleted objects to recover.This object doesn't have a change history. It probably wasn't added via this admin site.Usercommentdate createduserProject-Id-Version: PACKAGE VERSION Report-Msgid-Bugs-To: POT-Creation-Date: 2012-12-12 10:41+0100 PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE Last-Translator: Alexander Schoemaker Language-Team: Dutch Language: nl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1) Selecteer een datum uit de lijst om een verwijderde versie van het object te herstellen.Selecteer een datum uit de lijst om een vorige versie terug te plaatsen.ToelichtingDatum/tijdstip%(verbose_name)s is verwijderd.GeschiedenisEerste versie.Klik op onderstaande knop om deze versie van het object te herstellen.Klik op onderstaande knop om deze versie van het object terug te plaatsen.Herstel %(name)sHerstel verwijderde %(name)s%(name)s terugplaatsen%(verbose_name)s terugplaatsenVorige versie van %(datetime)s is teruggeplaatst%(model)s "%(name)s" is succesvol teruggeplaatst. Je kunt het nu opnieuw wijzigen.Er zijn geen verwijderde objecten die hersteld kunnen worden.Dit object bevat geen wijzigingshistorie. Vermoedelijk is het niet vanuit sitebeheer toegevoegd.Gebruikertoelichtingdatum aangemaaktgebruikerdjango-reversion-2.0.13/reversion/locale/nl/LC_MESSAGES/django.po000066400000000000000000000073671323160775000243450ustar00rootroot00000000000000# Dutch translations for django-reversion extension # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # Alexander Schoemaker , 2012. # Bouke Haarsma , 2013. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2012-12-12 10:41+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Alexander Schoemaker \n" "Language-Team: Dutch\n" "Language: nl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" #: admin.py:141 msgid "Initial version." msgstr "Eerste versie." #: admin.py:163 #, python-format msgid "Deleted %(verbose_name)s." msgstr "%(verbose_name)s is verwijderd." #: admin.py:186 templates/reversion/change_list.html:7 #: templates/reversion/recover_form.html:11 #: templates/reversion/recover_list.html:11 #, python-format msgid "Recover deleted %(name)s" msgstr "Herstel verwijderde %(name)s" #: admin.py:297 #, python-format msgid "Reverted to previous version, saved on %(datetime)s" msgstr "Vorige versie van %(datetime)s is teruggeplaatst" #: admin.py:299 #, python-format msgid "" "The %(model)s \"%(name)s\" was reverted successfully. You may edit it again " "below." msgstr "" "%(model)s \"%(name)s\" is succesvol teruggeplaatst. Je kunt het nu opnieuw " "wijzigen." #: admin.py:385 #, python-format msgid "Recover %(name)s" msgstr "Herstel %(name)s" #: admin.py:399 #, python-format msgid "Revert %(name)s" msgstr "%(name)s terugplaatsen" #: models.py:68 msgid "date created" msgstr "datum aangemaakt" #: models.py:74 msgid "user" msgstr "gebruiker" #: models.py:78 msgid "comment" msgstr "toelichting" #: templates/reversion/object_history.html:8 msgid "" "Choose a date from the list below to revert to a previous version of this " "object." msgstr "" "Selecteer een datum uit de lijst om een vorige versie terug te plaatsen." #: templates/reversion/object_history.html:15 #: templates/reversion/recover_list.html:24 msgid "Date/time" msgstr "Datum/tijdstip" #: templates/reversion/object_history.html:16 msgid "User" msgstr "Gebruiker" #: templates/reversion/object_history.html:17 msgid "Comment" msgstr "Toelichting" #: templates/reversion/object_history.html:36 msgid "" "This object doesn't have a change history. It probably wasn't added via this " "admin site." msgstr "" "Dit object bevat geen wijzigingshistorie. Vermoedelijk is het niet " "vanuit sitebeheer toegevoegd." #: templates/reversion/recover_form.html:8 #: templates/reversion/recover_list.html:8 #: templates/reversion/revision_form.html:8 msgid "Home" msgstr "" #: templates/reversion/recover_form.html:18 msgid "Press the save button below to recover this version of the object." msgstr "" "Klik op onderstaande knop om deze versie van het object te herstellen." #: templates/reversion/recover_list.html:18 msgid "" "Choose a date from the list below to recover a deleted version of an object." msgstr "" "Selecteer een datum uit de lijst om een verwijderde versie van het object " "te herstellen." #: templates/reversion/recover_list.html:38 msgid "There are no deleted objects to recover." msgstr "Er zijn geen verwijderde objecten die hersteld kunnen worden." #: templates/reversion/revision_form.html:12 msgid "History" msgstr "Geschiedenis" #: templates/reversion/revision_form.html:13 #, python-format msgid "Revert %(verbose_name)s" msgstr "%(verbose_name)s terugplaatsen" #: templates/reversion/revision_form.html:26 msgid "Press the save button below to revert to this version of the object." msgstr "" "Klik op onderstaande knop om deze versie van het object terug te plaatsen." django-reversion-2.0.13/reversion/locale/pl/000077500000000000000000000000001323160775000207435ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/pl/LC_MESSAGES/000077500000000000000000000000001323160775000225305ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/pl/LC_MESSAGES/django.mo000066400000000000000000000047361323160775000243410ustar00rootroot00000000000000ޕԌ LQcµ˝ Í×ńůţBDR—¨ Áâň3 P>(ŹX¸JaNpSż   )3NWgHxHÁ %:`t8]É7' r_ Ň     Add %(name)sChoose a date from the list below to recover a deleted version of an object.Choose a date from the list below to revert to a previous version of this object.CommentDATETIME_FORMATDate/timeDeleted %(verbose_name)s.HistoryHomeInitial version.Press the save button below to recover this version of the object.Press the save button below to revert to this version of the object.Recover %(name)sRecover deleted %(name)sRecover deleted %(verbose_name)sRevert %(name)sRevert %(verbose_name)sReverted to previous version, saved on %(datetime)sThe %(model)s "%(name)s" was reverted successfully. You may edit it again below.There are no deleted objects to recover.This object doesn't have a change history. It probably wasn't added via this admin site.UserProject-Id-Version: reversion Report-Msgid-Bugs-To: POT-Creation-Date: 2011-03-21 20:05+0100 PO-Revision-Date: 2011-03-21 20:12+0100 Last-Translator: Zbigniew Siciarz Language-Team: LANGUAGE Language: pl MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Dodaj %(name)sWybierz datÄ™ z poniĹĽszej listy, by przywrĂłcić usuniÄ™tÄ… wersjÄ™ obiektu. Wybierz datÄ™ z poniĹĽszej listy, by przywrĂłcić ten obiekt do poprzedniej wersji.Komentarzj. N Y, H:iData/czasUsuniÄ™to %(verbose_name)sHistoriaStrona głównaPierwsza wersja.NaciĹ›nij przycisk Zapisz poniĹĽej, by przywrĂłcić tÄ™ wersjÄ™ obiektu.NaciĹ›nij przycisk Zapisz poniĹĽej, by przywrĂłcić tÄ™ wersjÄ™ obiektu.Przywróć %(name)sOdzyskaj usuniÄ™te %(name)sPrzywróć usuniÄ™te %(verbose_name)sPrzywróć %(name)sPrzywróć %(verbose_name)sPrzywrĂłcono poprzedniÄ… wersjÄ™, zapisanÄ… %(datetime)s%(model)s "%(name)s" zostaĹ‚ pomyĹ›lnie przywrĂłcony. MoĹĽesz go ponownie edytować poniĹĽej.Nie ma ĹĽadnych usuniÄ™tych obiektĂłw do przywrĂłcenia.Ten obiekt nie posiada historii zmian. Prawdopodobnie nie zostaĹ‚ dodany za pomocÄ… tego panelu administracyjnego.UĹĽytkownikdjango-reversion-2.0.13/reversion/locale/pl/LC_MESSAGES/django.po000066400000000000000000000075001323160775000243340ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: reversion\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2011-03-21 20:05+0100\n" "PO-Revision-Date: 2011-03-21 20:12+0100\n" "Last-Translator: Zbigniew Siciarz \n" "Language-Team: LANGUAGE \n" "Language: pl\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: admin.py:100 msgid "Initial version." msgstr "Pierwsza wersja." #: admin.py:115 #, python-format msgid "Deleted %(verbose_name)s." msgstr "UsuniÄ™to %(verbose_name)s" #: admin.py:127 #: templates/reversion/change_list.html:8 #: templates/reversion/recover_list.html:10 #, python-format msgid "Recover deleted %(name)s" msgstr "Odzyskaj usuniÄ™te %(name)s" #: admin.py:218 #, python-format msgid "Reverted to previous version, saved on %(datetime)s" msgstr "PrzywrĂłcono poprzedniÄ… wersjÄ™, zapisanÄ… %(datetime)s" #: admin.py:220 #, python-format msgid "The %(model)s \"%(name)s\" was reverted successfully. You may edit it again below." msgstr "%(model)s \"%(name)s\" zostaĹ‚ pomyĹ›lnie przywrĂłcony. MoĹĽesz go ponownie edytować poniĹĽej." #: admin.py:321 #, python-format msgid "Recover %(name)s" msgstr "Przywróć %(name)s" #: admin.py:332 #, python-format msgid "Revert %(name)s" msgstr "Przywróć %(name)s" #: templates/reversion/change_list.html:11 #, python-format msgid "Add %(name)s" msgstr "Dodaj %(name)s" #: templates/reversion/object_history.html:8 msgid "Choose a date from the list below to revert to a previous version of this object." msgstr "Wybierz datÄ™ z poniĹĽszej listy, by przywrĂłcić ten obiekt do poprzedniej wersji." #: templates/reversion/object_history.html:15 #: templates/reversion/recover_list.html:23 msgid "Date/time" msgstr "Data/czas" #: templates/reversion/object_history.html:16 msgid "User" msgstr "UĹĽytkownik" #: templates/reversion/object_history.html:17 msgid "Comment" msgstr "Komentarz" #: templates/reversion/object_history.html:23 #: templates/reversion/recover_list.html:30 msgid "DATETIME_FORMAT" msgstr "j. N Y, H:i" #: templates/reversion/object_history.html:31 msgid "This object doesn't have a change history. It probably wasn't added via this admin site." msgstr "Ten obiekt nie posiada historii zmian. Prawdopodobnie nie zostaĹ‚ dodany za pomocÄ… tego panelu administracyjnego." #: templates/reversion/recover_form.html:7 #: templates/reversion/recover_list.html:7 #: templates/reversion/revision_form.html:10 msgid "Home" msgstr "Strona główna" #: templates/reversion/recover_form.html:10 #, python-format msgid "Recover deleted %(verbose_name)s" msgstr "Przywróć usuniÄ™te %(verbose_name)s" #: templates/reversion/recover_form.html:17 msgid "Press the save button below to recover this version of the object." msgstr "NaciĹ›nij przycisk Zapisz poniĹĽej, by przywrĂłcić tÄ™ wersjÄ™ obiektu." #: templates/reversion/recover_list.html:17 msgid "Choose a date from the list below to recover a deleted version of an object." msgstr "Wybierz datÄ™ z poniĹĽszej listy, by przywrĂłcić usuniÄ™tÄ… wersjÄ™ obiektu. " #: templates/reversion/recover_list.html:37 msgid "There are no deleted objects to recover." msgstr "Nie ma ĹĽadnych usuniÄ™tych obiektĂłw do przywrĂłcenia." #: templates/reversion/revision_form.html:14 msgid "History" msgstr "Historia" #: templates/reversion/revision_form.html:15 #, python-format msgid "Revert %(verbose_name)s" msgstr "Przywróć %(verbose_name)s" #: templates/reversion/revision_form.html:28 msgid "Press the save button below to revert to this version of the object." msgstr "NaciĹ›nij przycisk Zapisz poniĹĽej, by przywrĂłcić tÄ™ wersjÄ™ obiektu." #~ msgid "Recover %s" #~ msgstr "Przywróć %s" django-reversion-2.0.13/reversion/locale/pt_BR/000077500000000000000000000000001323160775000213365ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/pt_BR/LC_MESSAGES/000077500000000000000000000000001323160775000231235ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/pt_BR/LC_MESSAGES/django.mo000066400000000000000000000045111323160775000247230ustar00rootroot00000000000000Ţ•Älŕ áLîQ;Ť• ĄŻ·BĽD˙DU nŹź3·Pë(<XeľKĂS"Vv Í Ů ä îůIţMH–©$Ćëý6SN+˘qÎ@     Add %(name)sChoose a date from the list below to recover a deleted version of an object.Choose a date from the list below to revert to a previous version of this object.CommentDATETIME_FORMATDate/timeHistoryHomePress the save button below to recover this version of the object.Press the save button below to revert to this version of the object.Recover %(name)sRecover deleted %(name)sRecover deleted %(verbose_name)sRevert %(name)sRevert %(verbose_name)sReverted to previous version, saved on %(datetime)sThe %(model)s "%(name)s" was reverted successfully. You may edit it again below.There are no deleted objects to recover.This object doesn't have a change history. It probably wasn't added via this admin site.UserProject-Id-Version: PACKAGE VERSION Report-Msgid-Bugs-To: POT-Creation-Date: 2009-08-29 13:04+0200 PO-Revision-Date: 2009-08-29 13:44+0100 Last-Translator: Partec Language-Team: Tangerina Lab MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adicionar %(name)sEscolha uma data da lista abaixo para recuperar uma versĂŁo excluĂ­da de um objeto.Escolha uma data da lista abaixo para reverter para uma versĂŁo anterior deste objeto.Comentáriod/m/Y, G:iData/horaHistĂłricoHomePressione o botĂŁo salvar, abaixo, para recuperar essa versĂŁo do objeto.Pressione o botĂŁo salvar, abaixo, para reverter para essa versĂŁo do objeto.Recuperar %(name)sRecuperar %(name)s excluĂ­doRecuperar %(verbose_name)s excluĂ­doReverter %(name)sReverter %(verbose_name)sRevertido para versĂŁo anterior, salva em %(datetime)s%(model)s "%(name)s" foi revertido com sucesso. VocĂŞ pode editar novamente abaixo.NĂŁo há objetos excluĂ­dos para recuperar.Este objeto nĂŁo possui um histĂłrico de mudanças. Ele provavelmente nĂŁo foi adicionado por este site de admin.Usuáriodjango-reversion-2.0.13/reversion/locale/pt_BR/LC_MESSAGES/django.po000066400000000000000000000073331323160775000247330ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2009-08-29 13:04+0200\n" "PO-Revision-Date: 2009-08-29 13:44+0100\n" "Last-Translator: Partec \n" "Language-Team: Tangerina Lab \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" #: .\admin.py:128 #: .\templates\reversion\change_list.html.py:7 #: .\templates\reversion\recover_list.html.py:10 msgid "Recover deleted %(name)s" msgstr "Recuperar %(name)s excluĂ­do" #: .\admin.py:173 #, python-format msgid "Reverted to previous version, saved on %(datetime)s" msgstr "Revertido para versĂŁo anterior, salva em %(datetime)s" #: .\admin.py:175 #, python-format msgid "The %(model)s \"%(name)s\" was reverted successfully. You may edit it again below." msgstr "%(model)s \"%(name)s\" foi revertido com sucesso. VocĂŞ pode editar novamente abaixo." #: .\admin.py:271 #, python-format msgid "Recover %(name)s" msgstr "Recuperar %(name)s" #: .\admin.py:281 #, python-format msgid "Revert %(name)s" msgstr "Reverter %(name)s" #: .\templates\reversion\change_list.html.py:9 #, python-format msgid "Add %(name)s" msgstr "Adicionar %(name)s" #: .\templates\reversion\object_history.html.py:8 msgid "Choose a date from the list below to revert to a previous version of this object." msgstr "Escolha uma data da lista abaixo para reverter para uma versĂŁo anterior deste objeto." #: .\templates\reversion\object_history.html.py:15 #: .\templates\reversion\recover_list.html.py:23 msgid "Date/time" msgstr "Data/hora" #: .\templates\reversion\object_history.html.py:16 msgid "User" msgstr "Usuário" #: .\templates\reversion\object_history.html.py:17 msgid "Comment" msgstr "Comentário" #: .\templates\reversion\object_history.html.py:23 #: .\templates\reversion\recover_list.html.py:30 msgid "DATETIME_FORMAT" msgstr "d/m/Y, G:i" #: .\templates\reversion\object_history.html.py:31 msgid "This object doesn't have a change history. It probably wasn't added via this admin site." msgstr "Este objeto nĂŁo possui um histĂłrico de mudanças. Ele provavelmente nĂŁo foi adicionado por este site de admin." #: .\templates\reversion\recover_form.html.py:14 #: .\templates\reversion\recover_list.html.py:7 #: .\templates\reversion\revision_form.html.py:14 msgid "Home" msgstr "Home" #: .\templates\reversion\recover_form.html.py:17 #, python-format msgid "Recover deleted %(verbose_name)s" msgstr "Recuperar %(verbose_name)s excluĂ­do" #: .\templates\reversion\recover_form.html.py:24 msgid "Press the save button below to recover this version of the object." msgstr "Pressione o botĂŁo salvar, abaixo, para recuperar essa versĂŁo do objeto." #: .\templates\reversion\recover_list.html.py:17 msgid "Choose a date from the list below to recover a deleted version of an object." msgstr "Escolha uma data da lista abaixo para recuperar uma versĂŁo excluĂ­da de um objeto." #: .\templates\reversion\recover_list.html.py:37 msgid "There are no deleted objects to recover." msgstr "NĂŁo há objetos excluĂ­dos para recuperar." #: .\templates\reversion\revision_form.html.py:18 msgid "History" msgstr "HistĂłrico" #: .\templates\reversion\revision_form.html.py:19 #, python-format msgid "Revert %(verbose_name)s" msgstr "Reverter %(verbose_name)s" #: .\templates\reversion\revision_form.html.py:32 msgid "Press the save button below to revert to this version of the object." msgstr "Pressione o botĂŁo salvar, abaixo, para reverter para essa versĂŁo do objeto." #~ msgid "Recover %s" #~ msgstr "Recuperar %s" django-reversion-2.0.13/reversion/locale/ru/000077500000000000000000000000001323160775000207565ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/ru/LC_MESSAGES/000077500000000000000000000000001323160775000225435ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/ru/LC_MESSAGES/django.mo000066400000000000000000000056551323160775000243550ustar00rootroot00000000000000Ţ•Ě|đ ńLţQKťĄ µżÇBĚDT ep ‰Şş3ŇP(WX€Ů~Ţ]€wř| “ť± Ŕ„ÍzR!Íď4 <@ } • ^µ o \„ ˛á ”     Add %(name)sChoose a date from the list below to recover a deleted version of an object.Choose a date from the list below to revert to a previous version of this object.CommentDATETIME_FORMATDate/timeHistoryHomePress the save button below to recover this version of the object.Press the save button below to revert to this version of the object.Recover %(name)sRecover %sRecover deleted %(name)sRecover deleted %(verbose_name)sRevert %(name)sRevert %(verbose_name)sReverted to previous version, saved on %(datetime)sThe %(model)s "%(name)s" was reverted successfully. You may edit it again below.There are no deleted objects to recover.This object doesn't have a change history. It probably wasn't added via this admin site.UserProject-Id-Version: reversion Report-Msgid-Bugs-To: POT-Creation-Date: 2009-02-03 08:31+0100 PO-Revision-Date: 2009-10-14 22:21+0300 Last-Translator: Alexander Yakovlev Language-Team: Russian MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Poedit-Language: Russian X-Poedit-Country: RUSSIAN FEDERATION Добавить %(name)sВыберите Đ´Đ°Ń‚Ń Đ¸Đ· ŃпиŃка, чтобы воŃŃтановить ŃдаленнŃŃŽ верŃию объекта.Выберите Đ´Đ°Ń‚Ń Đ¸Đ· ŃпиŃка, чтобы вернŃть предыдŃщŃŃŽ верŃию этого объекта.Комментарийd.m.Y H:iДата/времяĐŃторияНачалоНажмите ĐşĐ˝ĐľĐżĐşŃ "Сохранить" далее, чтобы воŃŃтановить ŃŤŃ‚Ń Đ˛ĐµŃ€Ńию объекта.Нажмите ĐşĐ˝ĐľĐżĐşŃ "Сохранить" далее, чтобы вернŃть ŃŤŃ‚Ń Đ˛ĐµŃ€Ńию объекта.Đ’ĐľŃŃтановить %(name)sĐ’ĐľŃŃтановить %sĐ’ĐľŃŃтановить Ńдаленный %(name)sĐ’ĐľŃŃтановить Ńдаленный %(verbose_name)sВернŃть %(name)sВернŃть %(verbose_name)sВозвращено Đş предыдŃщей верŃии, Ńохраненной %(datetime)s%(model)s "%(name)s" возвращен. Можете продолжить его редактирование.Не найдено Ńдаленных объектов для воŃŃтановления.ĐŁ этого объекта нет иŃтории изменений. Возможно, он был добавлен не через админиŃтраторŃкий Ńайт.Пользовательdjango-reversion-2.0.13/reversion/locale/ru/LC_MESSAGES/django.po000066400000000000000000000103701323160775000243460ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # msgid "" msgstr "" "Project-Id-Version: reversion\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2009-02-03 08:31+0100\n" "PO-Revision-Date: 2009-10-14 22:21+0300\n" "Last-Translator: Alexander Yakovlev \n" "Language-Team: Russian \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "X-Poedit-Language: Russian\n" "X-Poedit-Country: RUSSIAN FEDERATION\n" #: admin.py:122 #: templates/reversion/change_list.html:8 #: templates/reversion/recover_list.html:9 #, python-format msgid "Recover deleted %(name)s" msgstr "Đ’ĐľŃŃтановить Ńдаленный %(name)s" #: admin.py:155 #, python-format msgid "Reverted to previous version, saved on %(datetime)s" msgstr "Возвращено Đş предыдŃщей верŃии, Ńохраненной %(datetime)s" #: admin.py:157 #, python-format msgid "The %(model)s \"%(name)s\" was reverted successfully. You may edit it again below." msgstr "%(model)s \"%(name)s\" возвращен. Можете продолжить его редактирование." #: admin.py:227 #, python-format msgid "Recover %s" msgstr "Đ’ĐľŃŃтановить %s" #: admin.py:243 #, python-format msgid "Revert %(name)s" msgstr "ВернŃть %(name)s" #: templates/reversion/change_list.html:11 #, python-format msgid "Add %(name)s" msgstr "Добавить %(name)s" #: templates/reversion/object_history.html:8 msgid "Choose a date from the list below to revert to a previous version of this object." msgstr "Выберите Đ´Đ°Ń‚Ń Đ¸Đ· ŃпиŃка, чтобы вернŃть предыдŃщŃŃŽ верŃию этого объекта." #: templates/reversion/object_history.html:15 #: templates/reversion/recover_list.html:21 msgid "Date/time" msgstr "Дата/время" #: templates/reversion/object_history.html:16 msgid "User" msgstr "Пользователь" #: templates/reversion/object_history.html:17 msgid "Comment" msgstr "Комментарий" #: templates/reversion/object_history.html:23 #: templates/reversion/recover_list.html:28 msgid "DATETIME_FORMAT" msgstr "d.m.Y H:i" #: templates/reversion/object_history.html:31 msgid "This object doesn't have a change history. It probably wasn't added via this admin site." msgstr "ĐŁ этого объекта нет иŃтории изменений. Возможно, он был добавлен не через админиŃтраторŃкий Ńайт." #: templates/reversion/recover_form.html:14 #: templates/reversion/recover_list.html:6 #: templates/reversion/revision_form.html:14 msgid "Home" msgstr "Начало" #: templates/reversion/recover_form.html:17 #, python-format msgid "Recover deleted %(verbose_name)s" msgstr "Đ’ĐľŃŃтановить Ńдаленный %(verbose_name)s" #: templates/reversion/recover_form.html:18 #, python-format msgid "Recover %(name)s" msgstr "Đ’ĐľŃŃтановить %(name)s" #: templates/reversion/recover_form.html:24 msgid "Press the save button below to recover this version of the object." msgstr "Нажмите ĐşĐ˝ĐľĐżĐşŃ \"Сохранить\" далее, чтобы воŃŃтановить ŃŤŃ‚Ń Đ˛ĐµŃ€Ńию объекта." #: templates/reversion/recover_list.html:15 msgid "Choose a date from the list below to recover a deleted version of an object." msgstr "Выберите Đ´Đ°Ń‚Ń Đ¸Đ· ŃпиŃка, чтобы воŃŃтановить ŃдаленнŃŃŽ верŃию объекта." #: templates/reversion/recover_list.html:35 msgid "There are no deleted objects to recover." msgstr "Не найдено Ńдаленных объектов для воŃŃтановления." #: templates/reversion/revision_form.html:18 msgid "History" msgstr "ĐŃтория" #: templates/reversion/revision_form.html:19 #, python-format msgid "Revert %(verbose_name)s" msgstr "ВернŃть %(verbose_name)s" #: templates/reversion/revision_form.html:32 msgid "Press the save button below to revert to this version of the object." msgstr "Нажмите ĐşĐ˝ĐľĐżĐşŃ \"Сохранить\" далее, чтобы вернŃть ŃŤŃ‚Ń Đ˛ĐµŃ€Ńию объекта." django-reversion-2.0.13/reversion/locale/sk/000077500000000000000000000000001323160775000207455ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/sk/LC_MESSAGES/000077500000000000000000000000001323160775000225325ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/sk/LC_MESSAGES/django.mo000066400000000000000000000046711323160775000243410ustar00rootroot00000000000000Ţ•Ě|đLńQ> ˘ŞŻBŔDHYr‚3šPÎ(XHˇ¦ ®»ŹŔTP[Ą   !'K=L‰Öč(0-3^Y’9ěZ& Ź ™ «     Choose a date from the list below to recover a deleted version of an object.Choose a date from the list below to revert to a previous version of this object.CommentDate/timeHistoryHomeInitial version.Press the save button below to recover this version of the object.Press the save button below to revert to this version of the object.Recover %(name)sRecover deleted %(name)sRevert %(name)sRevert %(verbose_name)sReverted to previous version, saved on %(datetime)sThe %(model)s "%(name)s" was reverted successfully. You may edit it again below.There are no deleted objects to recover.This object doesn't have a change history. It probably wasn't added via this admin site.Usercommentdate createduserProject-Id-Version: PACKAGE VERSION Report-Msgid-Bugs-To: POT-Creation-Date: 2014-01-14 19:05+0100 PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE Last-Translator: Juraj Bubniak Language-Team: Slovak Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2; Pre obnovenie vymazanej verzie objektu vyberte dátum z nižšie uvedenĂ©ho zoznamu.Vyberte dátum z nižšie uvedenĂ©ho zoznamu pre návrat k predošlej verzii tohto objektu.KomentárDátum/ÄŤasHistĂłriaDomovPoÄŤiatoÄŤná verzia.Pre obnovenie tejto verzie objektu kliknite na tlaÄŤidlo uloĹľiĹĄ nižšie.Pre návrat na tĂşto verziu objektu kliknite na tlaÄŤidlo uloĹľiĹĄ nižšie.ObnoviĹĄ %(name)sObnoviĹĄ vymazanĂ˝ %(name)sVrátiĹĄ sa k predošlej verzii %(name)sVrátiĹĄ sa k predošlej verzii %(verbose_name)sObnovená predošlá verzia, uloĹľená %(datetime)sObjekt %(model)s "%(name)s" bol Ăşspešne obnovenĂ˝. MĂ´Ĺľete ho znovu upraviĹĄ nižšie.NiesĂş dostupnĂ© Ĺľiadne vymazanĂ© objekty pre obnovenie.Tento objekt nemá histĂłriu zmien. Pravdepodobne nebol pridanĂ˝ cez tĂşto admin stránku.PoužívateÄľkomentárdátum vytvoreniapoužívateÄľdjango-reversion-2.0.13/reversion/locale/sk/LC_MESSAGES/django.po000066400000000000000000000072121323160775000243360ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-01-14 19:05+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Juraj Bubniak \n" "Language-Team: Slovak \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" #: admin.py:153 msgid "Initial version." msgstr "PoÄŤiatoÄŤná verzia." #: admin.py:187 templates/reversion/change_list.html:7 #: templates/reversion/recover_form.html:11 #: templates/reversion/recover_list.html:11 #, python-format msgid "Recover deleted %(name)s" msgstr "ObnoviĹĄ vymazanĂ˝ %(name)s" #: admin.py:304 #, python-format msgid "Reverted to previous version, saved on %(datetime)s" msgstr "Obnovená predošlá verzia, uloĹľená %(datetime)s" #: admin.py:306 #, python-format msgid "" "The %(model)s \"%(name)s\" was reverted successfully. You may edit it again " "below." msgstr "" "Objekt %(model)s \"%(name)s\" bol Ăşspešne obnovenĂ˝. MĂ´Ĺľete ho znovu upraviĹĄ " "nižšie." #: admin.py:391 #, python-format msgid "Recover %(name)s" msgstr "ObnoviĹĄ %(name)s" #: admin.py:405 #, python-format msgid "Revert %(name)s" msgstr "VrátiĹĄ sa k predošlej verzii %(name)s" #: models.py:55 msgid "date created" msgstr "dátum vytvorenia" #: models.py:61 msgid "user" msgstr "používateÄľ" #: models.py:65 msgid "comment" msgstr "komentár" #: templates/reversion/object_history.html:8 msgid "" "Choose a date from the list below to revert to a previous version of this " "object." msgstr "" "Vyberte dátum z nižšie uvedenĂ©ho zoznamu pre návrat k predošlej verzii tohto " "objektu." #: templates/reversion/object_history.html:15 #: templates/reversion/recover_list.html:24 msgid "Date/time" msgstr "Dátum/ÄŤas" #: templates/reversion/object_history.html:16 msgid "User" msgstr "PoužívateÄľ" #: templates/reversion/object_history.html:17 msgid "Comment" msgstr "Komentár" #: templates/reversion/object_history.html:36 msgid "" "This object doesn't have a change history. It probably wasn't added via this " "admin site." msgstr "" "Tento objekt nemá histĂłriu zmien. Pravdepodobne nebol pridanĂ˝ cez tĂşto " "admin stránku." #: templates/reversion/recover_form.html:8 #: templates/reversion/recover_list.html:8 #: templates/reversion/revision_form.html:8 msgid "Home" msgstr "Domov" #: templates/reversion/recover_form.html:18 msgid "Press the save button below to recover this version of the object." msgstr "Pre obnovenie tejto verzie objektu kliknite na tlaÄŤidlo uloĹľiĹĄ nižšie." #: templates/reversion/recover_list.html:18 msgid "" "Choose a date from the list below to recover a deleted version of an object." msgstr "" "Pre obnovenie vymazanej verzie objektu vyberte dátum z nižšie uvedenĂ©ho zoznamu." #: templates/reversion/recover_list.html:38 msgid "There are no deleted objects to recover." msgstr "NiesĂş dostupnĂ© Ĺľiadne vymazanĂ© objekty pre obnovenie." #: templates/reversion/revision_form.html:12 msgid "History" msgstr "HistĂłria" #: templates/reversion/revision_form.html:13 #, python-format msgid "Revert %(verbose_name)s" msgstr "VrátiĹĄ sa k predošlej verzii %(verbose_name)s" #: templates/reversion/revision_form.html:26 msgid "Press the save button below to revert to this version of the object." msgstr "Pre návrat na tĂşto verziu objektu kliknite na tlaÄŤidlo uloĹľiĹĄ nižšie." django-reversion-2.0.13/reversion/locale/sv/000077500000000000000000000000001323160775000207605ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/sv/LC_MESSAGES/000077500000000000000000000000001323160775000225455ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/sv/LC_MESSAGES/django.mo000066400000000000000000000047471323160775000243600ustar00rootroot00000000000000Ţ•Ü%ś0L1Q~ĐŘ čň B*Dm˛ĂÜě3P8(‰X˛  %j*M•lă P Z dn‘•B¨Dë0Dav8“WĚ/$ eT ş Ĺ Ď Ü     Choose a date from the list below to recover a deleted version of an object.Choose a date from the list below to revert to a previous version of this object.CommentDATETIME_FORMATDate/timeDeleted %(verbose_name)s.HistoryHomeInitial version.Press the save button below to recover this version of the object.Press the save button below to revert to this version of the object.Recover %(name)sRecover deleted %(name)sRevert %(name)sRevert %(verbose_name)sReverted to previous version, saved on %(datetime)sThe %(model)s "%(name)s" was reverted successfully. You may edit it again below.There are no deleted objects to recover.This object doesn't have a change history. It probably wasn't added via this admin site.Usercommentdate createduserProject-Id-Version: PACKAGE VERSION Report-Msgid-Bugs-To: POT-Creation-Date: 2012-06-13 09:56+0200 PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE Last-Translator: FULL NAME Language-Team: LANGUAGE Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=2; plural=(n != 1) Välj ett datum i listan här nedan för att ĂĄterskapa en borttagen version.Välj ett datum frĂĄn listan här under för att ĂĄterställa till en tidigare version av det här objektet.KommentarY-m-d H:iDatum/tidTog bort %(verbose_name)sHistorikHemFörsta versionen.Tryck pĂĄ spara här nedan fär att ĂĄterskapa den här versionen.Tryck pĂĄ spara här nedan för att ĂĄterställa den här versionen.Ă…terskapa %(name)sĂ…terskapa bortagna %(name)sĂ…terställ %(name)sĂ…terställ %(verbose_name)sĂ…tergick till föregĂĄende version, sparad %(datetime)sĂ…terställandet av %(model)s "%(name)s" lyckades. Du kan redigera den igen här nedan.Det finns inga borttagna objekt att ĂĄterskapa.Det här objektet saknar ändringshistorik. Det skapades förmodligen inte via den här admin-sajten.Användarekommentardatum skapadanvändaredjango-reversion-2.0.13/reversion/locale/sv/LC_MESSAGES/django.po000066400000000000000000000074611323160775000243570ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2012-06-13 09:56+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" #: admin.py:139 msgid "Initial version." msgstr "Första versionen." #: admin.py:161 #, python-format msgid "Deleted %(verbose_name)s." msgstr "Tog bort %(verbose_name)s" #: admin.py:181 templates/reversion/change_list.html:7 #: templates/reversion/recover_form.html:10 #: templates/reversion/recover_list.html:10 #, python-format msgid "Recover deleted %(name)s" msgstr "Ă…terskapa bortagna %(name)s" #: admin.py:292 #, python-format msgid "Reverted to previous version, saved on %(datetime)s" msgstr "Ă…tergick till föregĂĄende version, sparad %(datetime)s" #: admin.py:292 admin.py:456 templates/reversion/object_history.html:23 #: templates/reversion/recover_list.html:30 msgid "DATETIME_FORMAT" msgstr "Y-m-d H:i" #: admin.py:294 #, python-format msgid "" "The %(model)s \"%(name)s\" was reverted successfully. You may edit it again " "below." msgstr "" "Ă…terställandet av %(model)s \"%(name)s\" lyckades. Du kan redigera den igen " "här nedan." #: admin.py:377 #, python-format msgid "Recover %(name)s" msgstr "Ă…terskapa %(name)s" #: admin.py:388 #, python-format msgid "Revert %(name)s" msgstr "Ă…terställ %(name)s" #: models.py:68 msgid "date created" msgstr "datum skapad" #: models.py:74 msgid "user" msgstr "användare" #: models.py:78 msgid "comment" msgstr "kommentar" #: templates/reversion/object_history.html:8 msgid "" "Choose a date from the list below to revert to a previous version of this " "object." msgstr "" "Välj ett datum frĂĄn listan här under för att ĂĄterställa till en tidigare " "version av det här objektet." #: templates/reversion/object_history.html:15 #: templates/reversion/recover_list.html:23 msgid "Date/time" msgstr "Datum/tid" #: templates/reversion/object_history.html:16 msgid "User" msgstr "Användare" #: templates/reversion/object_history.html:17 msgid "Comment" msgstr "Kommentar" #: templates/reversion/object_history.html:36 msgid "" "This object doesn't have a change history. It probably wasn't added via this " "admin site." msgstr "" "Det här objektet saknar ändringshistorik. Det skapades förmodligen inte via " "den här admin-sajten." #: templates/reversion/recover_form.html:7 #: templates/reversion/recover_list.html:7 #: templates/reversion/revision_form.html:7 msgid "Home" msgstr "Hem" #: templates/reversion/recover_form.html:17 msgid "Press the save button below to recover this version of the object." msgstr "Tryck pĂĄ spara här nedan fär att ĂĄterskapa den här versionen." #: templates/reversion/recover_list.html:17 msgid "" "Choose a date from the list below to recover a deleted version of an object." msgstr "" "Välj ett datum i listan här nedan för att ĂĄterskapa en borttagen version." #: templates/reversion/recover_list.html:37 msgid "There are no deleted objects to recover." msgstr "Det finns inga borttagna objekt att ĂĄterskapa." #: templates/reversion/revision_form.html:11 msgid "History" msgstr "Historik" #: templates/reversion/revision_form.html:12 #, python-format msgid "Revert %(verbose_name)s" msgstr "Ă…terställ %(verbose_name)s" #: templates/reversion/revision_form.html:25 msgid "Press the save button below to revert to this version of the object." msgstr "Tryck pĂĄ spara här nedan för att ĂĄterställa den här versionen." django-reversion-2.0.13/reversion/locale/uk/000077500000000000000000000000001323160775000207475ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/uk/LC_MESSAGES/000077500000000000000000000000001323160775000225345ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/uk/LC_MESSAGES/django.mo000066400000000000000000000065731323160775000243460ustar00rootroot00000000000000Ţ•Ü%ś01L8Q…C×G<c  Ş˛·BČD PazŠ3˘(ÖX˙X] erďwg~nít†‚űk~ ę ú   y9 †ł : ,V  #ź cĂ W' ¤ $ 9 J f     ActionChoose a date from the list below to recover a deleted version of an object.Choose a date from the list below to revert to a previous version of this object.Could not load %(object_repr)s version - incompatible version data.Could not load %(object_repr)s version - unknown serializer %(format)s.Could not save %(object_repr)s version - missing dependency.Date/timeHistoryHomeInitial version.Press the save button below to recover this version of the object.Press the save button below to revert to this version of the object.Recover %(name)sRecover deleted %(name)sRevert %(name)sRevert %(verbose_name)sReverted to previous version, saved on %(datetime)sThere are no deleted objects to recover.This object doesn't have a change history. It probably wasn't added via this admin site.Usercommentdate createduserProject-Id-Version: django-reversion Report-Msgid-Bugs-To: https://github.com/etianen/django-reversion/issues POT-Creation-Date: 2017-11-03 12:02+0200 PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE Last-Translator: Illia Volochii Language-Team: Ukrainian Language: uk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2); ДіяВиберіть Đ´Đ°Ń‚Ń Ń–Đ· ŃпиŃĐşŃ Đ˝Đ¸Đ¶Ń‡Đµ, щоб відновити Đ˛Đ¸Đ´Đ°Đ»ĐµĐ˝Ń Đ˛ĐµŃ€ŃŃ–ŃŽ об'єкта.Виберіть Đ´Đ°Ń‚Ń Ń–Đ· ŃпиŃĐşŃ Đ˝Đ¸Đ¶Ń‡Đµ, щоб повернŃтиŃŃŹ Đ´Đľ попередньої верŃŃ–Ń— цього об'єкта.Неможливо завантажити верŃŃ–ŃŽ "%(object_repr)s" - неŃŃĐĽŃ–Ńні дані верŃŃ–Đą.Неможливо завантажити верŃŃ–ŃŽ "%(object_repr)s" - невідомий Ńеріалізатор %(format)s.Неможливо зберегти верŃŃ–ŃŽ "%(object_repr)s" - відŃŃтня залежніŃть.Дата/чаŃІŃторіяДомівкаПочаткова верŃŃ–ŃŹ.НатиŃніть ĐşĐ˝ĐľĐżĐşŃ "Зберегти" нижче, щоб відновити цю верŃŃ–ŃŽ об'єкта.НатиŃніть ĐşĐ˝ĐľĐżĐşŃ "Зберегти" нижче, щоб повернŃтиŃŃŹ Đ´Đľ цієї верŃŃ–Ń— об'єкта.Відновити %(name)sВідновити видалені %(name)sПовернŃти %(name)sПовернŃти %(verbose_name)sПовернŃто Đ´Đľ попередньої верŃŃ–Ń—, яка збережена %(datetime)sНе знайдено видалених об'єктів для відновлення.Цей об'єкт не має Ń–Ńторії Đ·ĐĽŃ–Đ˝. Напевно, він бŃв доданий не через цей Ńайт адмініŃтрŃвання.КориŃŃ‚Ńвачкоментардата ŃтвореннякориŃŃ‚Ńвачdjango-reversion-2.0.13/reversion/locale/uk/LC_MESSAGES/django.po000066400000000000000000000116111323160775000243360ustar00rootroot00000000000000# Translation of django-reversion into Ukrainian. # This file is distributed under the same license as the django-reversion package. # Illia Volochii , 2017. msgid "" msgstr "" "Project-Id-Version: django-reversion\n" "Report-Msgid-Bugs-To: https://github.com/etianen/django-reversion/issues\n" "POT-Creation-Date: 2017-11-03 12:02+0200\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: Illia Volochii \n" "Language-Team: Ukrainian\n" "Language: uk\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" "%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n" #: reversion/admin.py:83 msgid "Initial version." msgstr "Початкова верŃŃ–ŃŹ." #: reversion/admin.py:197 #, python-format msgid "Reverted to previous version, saved on %(datetime)s" msgstr "ПовернŃто Đ´Đľ попередньої верŃŃ–Ń—, яка збережена %(datetime)s" #: reversion/admin.py:221 #, python-format msgid "Recover %(name)s" msgstr "Відновити %(name)s" #: reversion/admin.py:237 #, python-format msgid "Revert %(name)s" msgstr "ПовернŃти %(name)s" #: reversion/admin.py:272 reversion/templates/reversion/change_list.html:7 #: reversion/templates/reversion/recover_form.html:10 #: reversion/templates/reversion/recover_list.html:10 #, python-format msgid "Recover deleted %(name)s" msgstr "Відновити видалені %(name)s" #: reversion/models.py:31 #, python-format msgid "Could not save %(object_repr)s version - missing dependency." msgstr "Неможливо зберегти верŃŃ–ŃŽ \"%(object_repr)s\" - відŃŃтня залежніŃть." #: reversion/models.py:45 msgid "date created" msgstr "дата Ńтворення" #: reversion/models.py:54 msgid "user" msgstr "кориŃŃ‚Ńвач" #: reversion/models.py:60 msgid "comment" msgstr "коментар" #: reversion/models.py:242 #, python-format msgid "Could not load %(object_repr)s version - incompatible version data." msgstr "" "Неможливо завантажити верŃŃ–ŃŽ \"%(object_repr)s\" - неŃŃĐĽŃ–Ńні дані верŃŃ–Đą." #: reversion/models.py:246 #, python-format msgid "Could not load %(object_repr)s version - unknown serializer %(format)s." msgstr "" "Неможливо завантажити верŃŃ–ŃŽ \"%(object_repr)s\" - невідомий Ńеріалізатор " "%(format)s." #: reversion/templates/reversion/object_history.html:8 msgid "" "Choose a date from the list below to revert to a previous version of this " "object." msgstr "" "Виберіть Đ´Đ°Ń‚Ń Ń–Đ· ŃпиŃĐşŃ Đ˝Đ¸Đ¶Ń‡Đµ, щоб повернŃтиŃŃŹ Đ´Đľ попередньої верŃŃ–Ń— цього " "об'єкта." #: reversion/templates/reversion/object_history.html:15 #: reversion/templates/reversion/recover_list.html:23 msgid "Date/time" msgstr "Дата/чаŃ" #: reversion/templates/reversion/object_history.html:16 msgid "User" msgstr "КориŃŃ‚Ńвач" #: reversion/templates/reversion/object_history.html:17 msgid "Action" msgstr "Дія" #: reversion/templates/reversion/object_history.html:38 msgid "" "This object doesn't have a change history. It probably wasn't added via this " "admin site." msgstr "" "Цей об'єкт не має Ń–Ńторії Đ·ĐĽŃ–Đ˝. Напевно, він бŃв доданий не через цей Ńайт " "адмініŃтрŃвання." #: reversion/templates/reversion/recover_form.html:7 #: reversion/templates/reversion/recover_list.html:7 #: reversion/templates/reversion/revision_form.html:7 msgid "Home" msgstr "Домівка" #: reversion/templates/reversion/recover_form.html:20 msgid "Press the save button below to recover this version of the object." msgstr "НатиŃніть ĐşĐ˝ĐľĐżĐşŃ \"Зберегти\" нижче, щоб відновити цю верŃŃ–ŃŽ об'єкта." #: reversion/templates/reversion/recover_list.html:17 msgid "" "Choose a date from the list below to recover a deleted version of an object." msgstr "Виберіть Đ´Đ°Ń‚Ń Ń–Đ· ŃпиŃĐşŃ Đ˝Đ¸Đ¶Ń‡Đµ, щоб відновити Đ˛Đ¸Đ´Đ°Đ»ĐµĐ˝Ń Đ˛ĐµŃ€ŃŃ–ŃŽ об'єкта." #: reversion/templates/reversion/recover_list.html:37 msgid "There are no deleted objects to recover." msgstr "Не знайдено видалених об'єктів для відновлення." #: reversion/templates/reversion/revision_form.html:11 msgid "History" msgstr "ІŃторія" #: reversion/templates/reversion/revision_form.html:12 #, python-format msgid "Revert %(verbose_name)s" msgstr "ПовернŃти %(verbose_name)s" #: reversion/templates/reversion/revision_form.html:21 msgid "Press the save button below to revert to this version of the object." msgstr "" "НатиŃніть ĐşĐ˝ĐľĐżĐşŃ \"Зберегти\" нижче, щоб повернŃтиŃŃŹ Đ´Đľ цієї верŃŃ–Ń— об'єкта." django-reversion-2.0.13/reversion/locale/zh_CN/000077500000000000000000000000001323160775000213315ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/zh_CN/LC_MESSAGES/000077500000000000000000000000001323160775000231165ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/zh_CN/LC_MESSAGES/django.mo000066400000000000000000000042071323160775000247200ustar00rootroot00000000000000Ţ•Ě|đLńQ> ˘ŞŻBŔDHYr‚3šPÎ(XHˇ¦ ®»dŔ9%?_ꦭ´ »*Č3ó'7Sc {Kś'čTel s€    Choose a date from the list below to recover a deleted version of an object.Choose a date from the list below to revert to a previous version of this object.CommentDate/timeHistoryHomeInitial version.Press the save button below to recover this version of the object.Press the save button below to revert to this version of the object.Recover %(name)sRecover deleted %(name)sRevert %(name)sRevert %(verbose_name)sReverted to previous version, saved on %(datetime)sThe %(model)s "%(name)s" was reverted successfully. You may edit it again below.There are no deleted objects to recover.This object doesn't have a change history. It probably wasn't added via this admin site.Usercommentdate createduserProject-Id-Version: PACKAGE VERSION Report-Msgid-Bugs-To: POT-Creation-Date: 2014-06-12 14:21+0800 PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE Last-Translator: FULL NAME Language-Team: LANGUAGE Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=1; plural=0; 单击下方的日期以ć˘ĺ¤Ťä¸€ä¸Şĺ·˛ĺ é™¤çš„对象。单击下方的日期以ć˘ĺ¤Ťĺ˝“前对象ĺ°äą‹ĺ‰Ťçš„ç‰ćś¬ă€‚评论时间历史首页ĺťĺ§‹ç‰ćś¬ĺŤ•击保ĺ­ćŚ‰é’®ä»Ąć˘ĺ¤Ťä¸şć­¤ç‰ćś¬ă€‚单击保ĺ­ćŚ‰é’®ĺ°†ć­¤ĺŻąč±ˇć˘ĺ¤Ťĺ°ć­¤ç‰ćś¬ă€‚ć˘ĺ¤Ť %(name)sć˘ĺ¤Ťĺ·˛ĺ é™¤çš„ %(name)sć˘ĺ¤Ť %(name)sć˘ĺ¤Ť %(verbose_name)sć˘ĺ¤Ťĺ° %(datetime)s çš„ç‰ćś¬%(model)s "%(name)s" ĺ·˛ć功ć˘ĺ¤ŤďĽŚä˝ ĺŹŻä»Ąĺś¨ä¸‹éť˘ĺś¨ć­¤çĽ–čľ‘ĺ®ă€‚没有可供ć˘ĺ¤Ťçš„ĺ·˛ĺ é™¤ĺŻąč±ˇă€‚ć­¤ĺŻąč±ˇä¸Ťĺ­ĺś¨ä»»ä˝•ĺŹć›´ĺŽ†ĺŹ˛ďĽŚĺ®ĺŹŻč˝ä¸ŤćŻé€ščż‡ç®ˇç†ç«™ç‚ąć·»ĺŠ çš„ă€‚ç”¨ć·čŻ„č®şĺ›ĺ»şć—Ąćśźç”¨ć·django-reversion-2.0.13/reversion/locale/zh_CN/LC_MESSAGES/django.po000066400000000000000000000065031323160775000247240ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-06-12 14:21+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" #: admin.py:160 msgid "Initial version." msgstr "ĺťĺ§‹ç‰ćś¬" #: admin.py:194 templates/reversion/change_list.html:7 #: templates/reversion/recover_form.html:11 #: templates/reversion/recover_list.html:11 #, python-format msgid "Recover deleted %(name)s" msgstr "ć˘ĺ¤Ťĺ·˛ĺ é™¤çš„ %(name)s" #: admin.py:311 #, python-format msgid "Reverted to previous version, saved on %(datetime)s" msgstr "ć˘ĺ¤Ťĺ° %(datetime)s çš„ç‰ćś¬" #: admin.py:313 #, python-format msgid "" "The %(model)s \"%(name)s\" was reverted successfully. You may edit it again " "below." msgstr "%(model)s \"%(name)s\" ĺ·˛ć功ć˘ĺ¤ŤďĽŚä˝ ĺŹŻä»Ąĺś¨ä¸‹éť˘ĺś¨ć­¤çĽ–čľ‘ĺ®ă€‚" #: admin.py:398 #, python-format msgid "Recover %(name)s" msgstr "ć˘ĺ¤Ť %(name)s" #: admin.py:412 #, python-format msgid "Revert %(name)s" msgstr "ć˘ĺ¤Ť %(name)s" #: models.py:55 msgid "date created" msgstr "ĺ›ĺ»şć—Ąćśź" #: models.py:62 msgid "user" msgstr "用ć·" #: models.py:66 msgid "comment" msgstr "评论" #: templates/reversion/object_history.html:8 msgid "" "Choose a date from the list below to revert to a previous version of this " "object." msgstr "单击下方的日期以ć˘ĺ¤Ťĺ˝“前对象ĺ°äą‹ĺ‰Ťçš„ç‰ćś¬ă€‚" #: templates/reversion/object_history.html:15 #: templates/reversion/recover_list.html:24 msgid "Date/time" msgstr "ć—¶é—´" #: templates/reversion/object_history.html:16 msgid "User" msgstr "用ć·" #: templates/reversion/object_history.html:17 msgid "Comment" msgstr "评论" #: templates/reversion/object_history.html:38 msgid "" "This object doesn't have a change history. It probably wasn't added via this " "admin site." msgstr "此对象不ĺ­ĺś¨ä»»ä˝•ĺŹć›´ĺŽ†ĺŹ˛ďĽŚĺ®ĺŹŻč˝ä¸ŤćŻé€ščż‡ç®ˇç†ç«™ç‚ąć·»ĺŠ çš„ă€‚" #: templates/reversion/recover_form.html:8 #: templates/reversion/recover_list.html:8 #: templates/reversion/revision_form.html:8 msgid "Home" msgstr "首页" #: templates/reversion/recover_form.html:18 msgid "Press the save button below to recover this version of the object." msgstr "单击保ĺ­ćŚ‰é’®ä»Ąć˘ĺ¤Ťä¸şć­¤ç‰ćś¬ă€‚" #: templates/reversion/recover_list.html:18 msgid "" "Choose a date from the list below to recover a deleted version of an object." msgstr "单击下方的日期以ć˘ĺ¤Ťä¸€ä¸Şĺ·˛ĺ é™¤çš„对象。" #: templates/reversion/recover_list.html:38 msgid "There are no deleted objects to recover." msgstr "没有可供ć˘ĺ¤Ťçš„ĺ·˛ĺ é™¤ĺŻąč±ˇă€‚" #: templates/reversion/revision_form.html:12 msgid "History" msgstr "历史" #: templates/reversion/revision_form.html:13 #, python-format msgid "Revert %(verbose_name)s" msgstr "ć˘ĺ¤Ť %(verbose_name)s" #: templates/reversion/revision_form.html:26 msgid "Press the save button below to revert to this version of the object." msgstr "单击保ĺ­ćŚ‰é’®ĺ°†ć­¤ĺŻąč±ˇć˘ĺ¤Ťĺ°ć­¤ç‰ćś¬ă€‚" django-reversion-2.0.13/reversion/locale/zh_Hans/000077500000000000000000000000001323160775000217225ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/zh_Hans/LC_MESSAGES/000077500000000000000000000000001323160775000235075ustar00rootroot00000000000000django-reversion-2.0.13/reversion/locale/zh_Hans/LC_MESSAGES/django.mo000066400000000000000000000042071323160775000253110ustar00rootroot00000000000000Ţ•Ě|đLńQ> ˘ŞŻBŔDHYr‚3šPÎ(XHˇ¦ ®»dŔ9%?_ꦭ´ »*Č3ó'7Sc {Kś'čTel s€    Choose a date from the list below to recover a deleted version of an object.Choose a date from the list below to revert to a previous version of this object.CommentDate/timeHistoryHomeInitial version.Press the save button below to recover this version of the object.Press the save button below to revert to this version of the object.Recover %(name)sRecover deleted %(name)sRevert %(name)sRevert %(verbose_name)sReverted to previous version, saved on %(datetime)sThe %(model)s "%(name)s" was reverted successfully. You may edit it again below.There are no deleted objects to recover.This object doesn't have a change history. It probably wasn't added via this admin site.Usercommentdate createduserProject-Id-Version: PACKAGE VERSION Report-Msgid-Bugs-To: POT-Creation-Date: 2014-06-12 14:21+0800 PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE Last-Translator: FULL NAME Language-Team: LANGUAGE Language: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Plural-Forms: nplurals=1; plural=0; 单击下方的日期以ć˘ĺ¤Ťä¸€ä¸Şĺ·˛ĺ é™¤çš„对象。单击下方的日期以ć˘ĺ¤Ťĺ˝“前对象ĺ°äą‹ĺ‰Ťçš„ç‰ćś¬ă€‚评论时间历史首页ĺťĺ§‹ç‰ćś¬ĺŤ•击保ĺ­ćŚ‰é’®ä»Ąć˘ĺ¤Ťä¸şć­¤ç‰ćś¬ă€‚单击保ĺ­ćŚ‰é’®ĺ°†ć­¤ĺŻąč±ˇć˘ĺ¤Ťĺ°ć­¤ç‰ćś¬ă€‚ć˘ĺ¤Ť %(name)sć˘ĺ¤Ťĺ·˛ĺ é™¤çš„ %(name)sć˘ĺ¤Ť %(name)sć˘ĺ¤Ť %(verbose_name)sć˘ĺ¤Ťĺ° %(datetime)s çš„ç‰ćś¬%(model)s "%(name)s" ĺ·˛ć功ć˘ĺ¤ŤďĽŚä˝ ĺŹŻä»Ąĺś¨ä¸‹éť˘ĺś¨ć­¤çĽ–čľ‘ĺ®ă€‚没有可供ć˘ĺ¤Ťçš„ĺ·˛ĺ é™¤ĺŻąč±ˇă€‚ć­¤ĺŻąč±ˇä¸Ťĺ­ĺś¨ä»»ä˝•ĺŹć›´ĺŽ†ĺŹ˛ďĽŚĺ®ĺŹŻč˝ä¸ŤćŻé€ščż‡ç®ˇç†ç«™ç‚ąć·»ĺŠ çš„ă€‚ç”¨ć·čŻ„č®şĺ›ĺ»şć—Ąćśźç”¨ć·django-reversion-2.0.13/reversion/locale/zh_Hans/LC_MESSAGES/django.po000066400000000000000000000065031323160775000253150ustar00rootroot00000000000000# SOME DESCRIPTIVE TITLE. # Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # FIRST AUTHOR , YEAR. # #, fuzzy msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" "POT-Creation-Date: 2014-06-12 14:21+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" "Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=1; plural=0;\n" #: admin.py:160 msgid "Initial version." msgstr "ĺťĺ§‹ç‰ćś¬" #: admin.py:194 templates/reversion/change_list.html:7 #: templates/reversion/recover_form.html:11 #: templates/reversion/recover_list.html:11 #, python-format msgid "Recover deleted %(name)s" msgstr "ć˘ĺ¤Ťĺ·˛ĺ é™¤çš„ %(name)s" #: admin.py:311 #, python-format msgid "Reverted to previous version, saved on %(datetime)s" msgstr "ć˘ĺ¤Ťĺ° %(datetime)s çš„ç‰ćś¬" #: admin.py:313 #, python-format msgid "" "The %(model)s \"%(name)s\" was reverted successfully. You may edit it again " "below." msgstr "%(model)s \"%(name)s\" ĺ·˛ć功ć˘ĺ¤ŤďĽŚä˝ ĺŹŻä»Ąĺś¨ä¸‹éť˘ĺś¨ć­¤çĽ–čľ‘ĺ®ă€‚" #: admin.py:398 #, python-format msgid "Recover %(name)s" msgstr "ć˘ĺ¤Ť %(name)s" #: admin.py:412 #, python-format msgid "Revert %(name)s" msgstr "ć˘ĺ¤Ť %(name)s" #: models.py:55 msgid "date created" msgstr "ĺ›ĺ»şć—Ąćśź" #: models.py:62 msgid "user" msgstr "用ć·" #: models.py:66 msgid "comment" msgstr "评论" #: templates/reversion/object_history.html:8 msgid "" "Choose a date from the list below to revert to a previous version of this " "object." msgstr "单击下方的日期以ć˘ĺ¤Ťĺ˝“前对象ĺ°äą‹ĺ‰Ťçš„ç‰ćś¬ă€‚" #: templates/reversion/object_history.html:15 #: templates/reversion/recover_list.html:24 msgid "Date/time" msgstr "ć—¶é—´" #: templates/reversion/object_history.html:16 msgid "User" msgstr "用ć·" #: templates/reversion/object_history.html:17 msgid "Comment" msgstr "评论" #: templates/reversion/object_history.html:38 msgid "" "This object doesn't have a change history. It probably wasn't added via this " "admin site." msgstr "此对象不ĺ­ĺś¨ä»»ä˝•ĺŹć›´ĺŽ†ĺŹ˛ďĽŚĺ®ĺŹŻč˝ä¸ŤćŻé€ščż‡ç®ˇç†ç«™ç‚ąć·»ĺŠ çš„ă€‚" #: templates/reversion/recover_form.html:8 #: templates/reversion/recover_list.html:8 #: templates/reversion/revision_form.html:8 msgid "Home" msgstr "首页" #: templates/reversion/recover_form.html:18 msgid "Press the save button below to recover this version of the object." msgstr "单击保ĺ­ćŚ‰é’®ä»Ąć˘ĺ¤Ťä¸şć­¤ç‰ćś¬ă€‚" #: templates/reversion/recover_list.html:18 msgid "" "Choose a date from the list below to recover a deleted version of an object." msgstr "单击下方的日期以ć˘ĺ¤Ťä¸€ä¸Şĺ·˛ĺ é™¤çš„对象。" #: templates/reversion/recover_list.html:38 msgid "There are no deleted objects to recover." msgstr "没有可供ć˘ĺ¤Ťçš„ĺ·˛ĺ é™¤ĺŻąč±ˇă€‚" #: templates/reversion/revision_form.html:12 msgid "History" msgstr "历史" #: templates/reversion/revision_form.html:13 #, python-format msgid "Revert %(verbose_name)s" msgstr "ć˘ĺ¤Ť %(verbose_name)s" #: templates/reversion/revision_form.html:26 msgid "Press the save button below to revert to this version of the object." msgstr "单击保ĺ­ćŚ‰é’®ĺ°†ć­¤ĺŻąč±ˇć˘ĺ¤Ťĺ°ć­¤ç‰ćś¬ă€‚" django-reversion-2.0.13/reversion/management/000077500000000000000000000000001323160775000212055ustar00rootroot00000000000000django-reversion-2.0.13/reversion/management/__init__.py000066400000000000000000000000001323160775000233040ustar00rootroot00000000000000django-reversion-2.0.13/reversion/management/commands/000077500000000000000000000000001323160775000230065ustar00rootroot00000000000000django-reversion-2.0.13/reversion/management/commands/__init__.py000066400000000000000000000037541323160775000251300ustar00rootroot00000000000000from __future__ import unicode_literals from django.apps import apps from django.contrib import admin from django.core.management.base import BaseCommand, CommandError from reversion.revisions import is_registered class BaseRevisionCommand(BaseCommand): def add_arguments(self, parser): super(BaseRevisionCommand, self).add_arguments(parser) parser.add_argument( "app_label", metavar="app_label", nargs="*", help="Optional app_label or app_label.model_name list.", ) parser.add_argument( "--using", default=None, help="The database to query for revision data.", ) parser.add_argument( "--model-db", default=None, help="The database to query for model data.", ) def get_models(self, options): # Load admin classes. admin.autodiscover() # Get options. app_labels = options["app_label"] # Parse model classes. if len(app_labels) == 0: selected_models = apps.get_models() else: selected_models = set() for label in app_labels: if "." in label: # This is an app.Model specifier. try: model = apps.get_model(label) except LookupError: raise CommandError("Unknown model: {}".format(label)) selected_models.add(model) else: # This is just an app - no model qualifier. app_label = label try: app = apps.get_app_config(app_label) except LookupError: raise CommandError("Unknown app: {}".format(app_label)) selected_models.update(app.get_models()) for model in selected_models: if is_registered(model): yield model django-reversion-2.0.13/reversion/management/commands/createinitialrevisions.py000066400000000000000000000061211323160775000301370ustar00rootroot00000000000000from __future__ import unicode_literals from django.db import reset_queries, transaction, router from reversion.models import Revision, Version, _safe_subquery from reversion.management.commands import BaseRevisionCommand from reversion.revisions import create_revision, set_comment, add_to_revision class Command(BaseRevisionCommand): help = "Creates initial revisions for a given app [and model]." def add_arguments(self, parser): super(Command, self).add_arguments(parser) parser.add_argument( "--comment", action="store", default="Initial version.", help="Specify the comment to add to the revisions. Defaults to 'Initial version'.") parser.add_argument( "--batch-size", action="store", type=int, default=500, help="For large sets of data, revisions will be populated in batches. Defaults to 500.", ) def handle(self, *app_labels, **options): verbosity = options["verbosity"] using = options["using"] model_db = options["model_db"] comment = options["comment"] batch_size = options["batch_size"] # Create revisions. using = using or router.db_for_write(Revision) with transaction.atomic(using=using): for model in self.get_models(options): # Check all models for empty revisions. if verbosity >= 1: self.stdout.write("Creating revisions for {name}".format( name=model._meta.verbose_name, )) created_count = 0 live_objs = _safe_subquery( "exclude", model._default_manager.using(model_db), model._meta.pk.name, Version.objects.using(using).get_for_model( model, model_db=model_db, ), "object_id", ) # Save all the versions. ids = list(live_objs.values_list("pk", flat=True).order_by()) total = len(ids) for i in range(0, total, batch_size): chunked_ids = ids[i:i+batch_size] objects = live_objs.in_bulk(chunked_ids) for obj in objects.values(): with create_revision(using=using): set_comment(comment) add_to_revision(obj, model_db=model_db) created_count += 1 reset_queries() if verbosity >= 2: self.stdout.write("- Created {created_count} / {total}".format( created_count=created_count, total=total, )) # Print out a message, if feeling verbose. if verbosity >= 1: self.stdout.write("- Created {total} / {total}".format( total=total, )) django-reversion-2.0.13/reversion/management/commands/deleterevisions.py000066400000000000000000000101051323160775000265610ustar00rootroot00000000000000from __future__ import unicode_literals from datetime import timedelta from django.db import transaction, models, router from django.utils import timezone from reversion.models import Revision, Version from reversion.management.commands import BaseRevisionCommand class Command(BaseRevisionCommand): help = "Deletes revisions for a given app [and model]." def add_arguments(self, parser): super(Command, self).add_arguments(parser) parser.add_argument( "--days", default=0, type=int, help="Delete only revisions older than the specified number of days.", ) parser.add_argument( "--keep", default=0, type=int, help="Keep the specified number of revisions (most recent) for each object.", ) def handle(self, *app_labels, **options): verbosity = options["verbosity"] using = options["using"] model_db = options["model_db"] days = options["days"] keep = options["keep"] # Delete revisions. using = using or router.db_for_write(Revision) with transaction.atomic(using=using): revision_query = models.Q() keep_revision_ids = set() # By default, delete nothing. can_delete = False # Get all revisions for the given revision manager and model. for model in self.get_models(options): if verbosity >= 1: self.stdout.write("Finding stale revisions for {name}".format( name=model._meta.verbose_name, )) # Find all matching revision IDs. model_query = Version.objects.using(using).get_for_model( model, model_db=model_db, ) if keep: overflow_object_ids = list(Version.objects.using(using).get_for_model( model, model_db=model_db, ).order_by().values_list("object_id").annotate( count=models.Count("object_id"), ).filter( count__gt=keep, ).values_list("object_id", flat=True).iterator()) # Only delete overflow revisions. model_query = model_query.filter(object_id__in=overflow_object_ids) for object_id in overflow_object_ids: if verbosity >= 2: self.stdout.write("- Finding stale revisions for {name} #{object_id}".format( name=model._meta.verbose_name, object_id=object_id, )) # But keep the underflow revisions. keep_revision_ids.update(Version.objects.using(using).get_for_object_reference( model, object_id, model_db=model_db, ).values_list("revision_id", flat=True)[:keep].iterator()) # Add to revision query. revision_query |= models.Q( pk__in=model_query.order_by().values_list("revision_id", flat=True) ) # If we have at least one model, then we can delete. can_delete = True if can_delete: revisions_to_delete = Revision.objects.using(using).filter( revision_query, date_created__lt=timezone.now() - timedelta(days=days), ).exclude( pk__in=keep_revision_ids ).order_by() else: revisions_to_delete = Revision.objects.using(using).none() # Print out a message, if feeling verbose. if verbosity >= 1: self.stdout.write("Deleting {total} revisions...".format( total=revisions_to_delete.count(), )) revisions_to_delete.delete() django-reversion-2.0.13/reversion/middleware.py000066400000000000000000000033411323160775000215610ustar00rootroot00000000000000import sys from reversion.revisions import create_revision as create_revision_base from reversion.views import _request_creates_revision, _set_user_from_request, create_revision class RevisionMiddleware(object): """Wraps the entire request in a revision.""" manage_manually = False using = None atomic = True def __init__(self, get_response=None): super(RevisionMiddleware, self).__init__() # Support Django 1.10 middleware. if get_response is not None: self.get_response = create_revision( manage_manually=self.manage_manually, using=self.using, atomic=self.atomic )(get_response) def process_request(self, request): if _request_creates_revision(request): context = create_revision_base( manage_manually=self.manage_manually, using=self.using, atomic=self.atomic ) context.__enter__() if not hasattr(request, "_revision_middleware"): setattr(request, "_revision_middleware", {}) request._revision_middleware[self] = context def _close_revision(self, request, is_exception): if self in getattr(request, "_revision_middleware", {}): _set_user_from_request(request) request._revision_middleware.pop(self).__exit__(*sys.exc_info() if is_exception else (None, None, None)) def process_response(self, request, response): self._close_revision(request, False) return response def process_exception(self, request, exception): self._close_revision(request, True) def __call__(self, request): return self.get_response(request) django-reversion-2.0.13/reversion/migrations/000077500000000000000000000000001323160775000212455ustar00rootroot00000000000000django-reversion-2.0.13/reversion/migrations/0001_initial.py000066400000000000000000000051561323160775000237170ustar00rootroot00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals from django.db import models, migrations import django.db.models.deletion from django.conf import settings class Migration(migrations.Migration): dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ('contenttypes', '0001_initial'), ] operations = [ migrations.CreateModel( name='Revision', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('manager_slug', models.CharField(default='default', max_length=200, db_index=True)), ('date_created', models.DateTimeField(auto_now_add=True, help_text='The date and time this revision was created.', verbose_name='date created', db_index=True)), ('comment', models.TextField(help_text='A text comment on this revision.', verbose_name='comment', blank=True)), ('user', models.ForeignKey(on_delete=django.db.models.deletion.SET_NULL, blank=True, to=settings.AUTH_USER_MODEL, help_text='The user who created this revision.', null=True, verbose_name='user')), ], options={ "ordering": ("-pk",) }, bases=(models.Model,), ), migrations.CreateModel( name='Version', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('object_id', models.TextField(help_text='Primary key of the model under version control.')), ('object_id_int', models.IntegerField(help_text="An indexed, integer version of the stored model's primary key, used for faster lookups.", null=True, db_index=True, blank=True)), ('format', models.CharField(help_text='The serialization format used by this model.', max_length=255)), ('serialized_data', models.TextField(help_text='The serialized form of this version of the model.')), ('object_repr', models.TextField(help_text='A string representation of the object.')), ('content_type', models.ForeignKey(help_text='Content type of the model under version control.', on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')), ('revision', models.ForeignKey(help_text='The revision that contains this version.', on_delete=django.db.models.deletion.CASCADE, to='reversion.Revision')), ], options={ "ordering": ("-pk",) }, bases=(models.Model,), ), ] django-reversion-2.0.13/reversion/migrations/0001_squashed_0004_auto_20160611_1202.py000066400000000000000000000054231323160775000272170ustar00rootroot00000000000000# -*- coding: utf-8 -*- # Generated by Django 1.9.7 on 2016-06-06 13:22 from __future__ import unicode_literals from django.conf import settings from django.db import migrations, models import django.db.models.deletion class Migration(migrations.Migration): replaces = [('reversion', '0001_initial'), ('reversion', '0002_auto_20141216_1509'), ('reversion', '0003_auto_20160601_1600'), ('reversion', '0004_auto_20160611_1202')] initial = True dependencies = [ migrations.swappable_dependency(settings.AUTH_USER_MODEL), ('contenttypes', '0001_initial'), ] operations = [ migrations.CreateModel( name='Revision', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('date_created', models.DateTimeField(db_index=True, help_text='The date and time this revision was created.', verbose_name='date created')), ('comment', models.TextField(blank=True, help_text='A text comment on this revision.', verbose_name='comment')), ('user', models.ForeignKey(blank=True, help_text='The user who created this revision.', null=True, on_delete=django.db.models.deletion.SET_NULL, to=settings.AUTH_USER_MODEL, verbose_name='user')), ], options={ "ordering": ("-pk",) }, ), migrations.CreateModel( name='Version', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('object_id', models.CharField(help_text='Primary key of the model under version control.', max_length=191)), ('format', models.CharField(help_text='The serialization format used by this model.', max_length=255)), ('serialized_data', models.TextField(help_text='The serialized form of this version of the model.')), ('object_repr', models.TextField(help_text='A string representation of the object.')), ('content_type', models.ForeignKey(help_text='Content type of the model under version control.', on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')), ('revision', models.ForeignKey(help_text='The revision that contains this version.', on_delete=django.db.models.deletion.CASCADE, to='reversion.Revision')), ('db', models.CharField(help_text='The database the model under version control is stored in.', max_length=191)), ], options={ "ordering": ("-pk",) }, ), migrations.AlterUniqueTogether( name='version', unique_together=set([('db', 'content_type', 'object_id', 'revision')]), ), ] django-reversion-2.0.13/reversion/migrations/0002_auto_20141216_1509.py000066400000000000000000000006641323160775000246740ustar00rootroot00000000000000# -*- coding: utf-8 -*- from __future__ import unicode_literals from django.db import models, migrations class Migration(migrations.Migration): dependencies = [ ('reversion', '0001_initial'), ] operations = [ migrations.AlterField( model_name='revision', name='manager_slug', field=models.CharField(default='default', max_length=191, db_index=True), ), ] django-reversion-2.0.13/reversion/migrations/0003_auto_20160601_1600.py000066400000000000000000000101531323160775000246560ustar00rootroot00000000000000# -*- coding: utf-8 -*- # Generated by Django 1.9.6 on 2016-06-01 16:00 from __future__ import unicode_literals from collections import defaultdict from django.db import DEFAULT_DB_ALIAS, migrations, models, router from django.apps import apps as live_apps def de_dupe_version_table(apps, schema_editor): """ Removes some duplicate Version models that may have crept into the database and will prevent the unique index being added by migration 0004. """ db_alias = schema_editor.connection.alias Version = apps.get_model("reversion", "Version") keep_version_ids = Version.objects.using(db_alias).order_by().values_list( # Group by the unique constraint we intend to enforce. "revision_id", "content_type_id", "object_id", ).annotate( # Add in the most recent id for each duplicate row. max_pk=models.Max("pk"), ).values_list("max_pk", flat=True) # Do not do anything if we're keeping all ids anyway. if keep_version_ids.count() == Version.objects.using(db_alias).all().count(): return # Delete all duplicate versions. Can't do this as a delete with subquery because MySQL doesn't like running a # subquery on the table being updated/deleted. delete_version_ids = list(Version.objects.using(db_alias).exclude( pk__in=keep_version_ids, ).values_list("pk", flat=True)) Version.objects.using(db_alias).filter( pk__in=delete_version_ids, ).delete() def set_version_db(apps, schema_editor): """ Updates the db field in all Version models to point to the correct write db for the model. """ db_alias = schema_editor.connection.alias Version = apps.get_model("reversion", "Version") content_types = Version.objects.using(db_alias).order_by().values_list( "content_type_id", "content_type__app_label", "content_type__model" ).distinct() model_dbs = defaultdict(list) for content_type_id, app_label, model_name in content_types: # We need to be able to access all models in the project, and we can't # specify them up-front in the migration dependencies. So we have to # just get the live model. This should be fine, since we don't actually # manipulate the live model in any way. try: model = live_apps.get_model(app_label, model_name) except LookupError: # If the model appears not to exist, play it safe and use the default db. db = "default" else: db = router.db_for_write(model) model_dbs[db].append(content_type_id) # Update db field. # speedup for case when there is only default db if DEFAULT_DB_ALIAS in model_dbs and len(model_dbs) == 1: Version.objects.using(db_alias).update(db=DEFAULT_DB_ALIAS) else: for db, content_type_ids in model_dbs.items(): Version.objects.using(db_alias).filter( content_type__in=content_type_ids ).update(db=db) class Migration(migrations.Migration): dependencies = [ ('reversion', '0002_auto_20141216_1509'), ] operations = [ migrations.RemoveField( model_name='revision', name='manager_slug', ), migrations.RemoveField( model_name='version', name='object_id_int', ), migrations.AlterField( model_name='version', name='object_id', field=models.CharField(help_text='Primary key of the model under version control.', max_length=191), ), migrations.AlterField( model_name='revision', name='date_created', field=models.DateTimeField(db_index=True, help_text='The date and time this revision was created.', verbose_name='date created'), ), migrations.AddField( model_name='version', name='db', field=models.CharField(null=True, help_text='The database the model under version control is stored in.', max_length=191), ), migrations.RunPython(de_dupe_version_table), migrations.RunPython(set_version_db), ] django-reversion-2.0.13/reversion/migrations/0004_auto_20160611_1202.py000066400000000000000000000012551323160775000246610ustar00rootroot00000000000000# -*- coding: utf-8 -*- # Generated by Django 1.9.7 on 2016-06-11 12:02 from __future__ import unicode_literals from django.db import migrations, models class Migration(migrations.Migration): dependencies = [ ('reversion', '0003_auto_20160601_1600'), ] operations = [ migrations.AlterField( model_name='version', name='db', field=models.CharField(help_text='The database the model under version control is stored in.', max_length=191), ), migrations.AlterUniqueTogether( name='version', unique_together=set([('db', 'content_type', 'object_id', 'revision')]), ), ] django-reversion-2.0.13/reversion/migrations/__init__.py000066400000000000000000000000001323160775000233440ustar00rootroot00000000000000django-reversion-2.0.13/reversion/models.py000066400000000000000000000325601323160775000207340ustar00rootroot00000000000000from __future__ import unicode_literals from collections import defaultdict from itertools import chain from django.contrib.contenttypes.models import ContentType try: from django.contrib.contenttypes.fields import GenericForeignKey except ImportError: # Django < 1.9 pragma: no cover from django.contrib.contenttypes.generic import GenericForeignKey from django.conf import settings from django.core import serializers from django.core.serializers.base import DeserializationError from django.core.exceptions import ObjectDoesNotExist from django.db import models, IntegrityError, transaction, router, connections from django.db.models.deletion import Collector from django.db.models.expressions import RawSQL from django.utils.functional import cached_property from django.utils.translation import ugettext_lazy as _, ugettext from django.utils.encoding import force_text, python_2_unicode_compatible from reversion.errors import RevertError from reversion.revisions import _get_options, _get_content_type, _follow_relations_recursive def _safe_revert(versions): unreverted_versions = [] for version in versions: try: with transaction.atomic(using=version.db): version.revert() except (IntegrityError, ObjectDoesNotExist): unreverted_versions.append(version) if len(unreverted_versions) == len(versions): raise RevertError(ugettext("Could not save %(object_repr)s version - missing dependency.") % { "object_repr": unreverted_versions[0], }) if unreverted_versions: _safe_revert(unreverted_versions) @python_2_unicode_compatible class Revision(models.Model): """A group of related serialized versions.""" date_created = models.DateTimeField( db_index=True, verbose_name=_("date created"), help_text="The date and time this revision was created.", ) user = models.ForeignKey( settings.AUTH_USER_MODEL, blank=True, null=True, on_delete=models.SET_NULL, verbose_name=_("user"), help_text="The user who created this revision.", ) comment = models.TextField( blank=True, verbose_name=_("comment"), help_text="A text comment on this revision.", ) def revert(self, delete=False): # Group the models by the database of the serialized model. versions_by_db = defaultdict(list) for version in self.version_set.iterator(): versions_by_db[version.db].append(version) # For each db, perform a separate atomic revert. for version_db, versions in versions_by_db.items(): with transaction.atomic(using=version_db): # Optionally delete objects no longer in the current revision. if delete: # Get a set of all objects in this revision. old_revision = set() for version in versions: model = version._model try: # Load the model instance from the same DB as it was saved under. old_revision.add(model._default_manager.using(version.db).get(pk=version.object_id)) except model.DoesNotExist: pass # Calculate the set of all objects that are in the revision now. current_revision = chain.from_iterable( _follow_relations_recursive(obj) for obj in old_revision ) # Delete objects that are no longer in the current revision. collector = Collector(using=version_db) collector.collect([item for item in current_revision if item not in old_revision]) collector.delete() # Attempt to revert all revisions. _safe_revert(versions) def __str__(self): return ", ".join(force_text(version) for version in self.version_set.all()) class Meta: app_label = "reversion" ordering = ("-pk",) class SubquerySQL(RawSQL): def as_sql(self, compiler, connection): return self.sql, self.params class VersionQuerySet(models.QuerySet): def get_for_model(self, model, model_db=None): model_db = model_db or router.db_for_write(model) content_type = _get_content_type(model, self.db) return self.filter( content_type=content_type, db=model_db, ) def get_for_object_reference(self, model, object_id, model_db=None): return self.get_for_model(model, model_db=model_db).filter( object_id=object_id, ) def get_for_object(self, obj, model_db=None): return self.get_for_object_reference(obj.__class__, obj.pk, model_db=model_db) def get_deleted(self, model, model_db=None): # Try to do a faster JOIN. model_db = model_db or router.db_for_write(model) connection = connections[self.db] if self.db == model_db and connection.vendor in ("sqlite", "postgresql", "oracle"): content_type = _get_content_type(model, self.db) subquery = SubquerySQL( """ SELECT MAX(V.{id}) FROM {version} V LEFT JOIN {model} ON V.{object_id} = CAST({model}.{model_id} as {str}) WHERE V.{db} = %s AND V.{content_type_id} = %s AND {model}.{model_id} IS NULL GROUP BY V.{object_id} """.format( id=connection.ops.quote_name("id"), version=connection.ops.quote_name(Version._meta.db_table), model=connection.ops.quote_name(model._meta.db_table), model_id=connection.ops.quote_name(model._meta.pk.db_column or model._meta.pk.attname), object_id=connection.ops.quote_name("object_id"), str=Version._meta.get_field("object_id").db_type(connection), db=connection.ops.quote_name("db"), content_type_id=connection.ops.quote_name("content_type_id"), ), (model_db, content_type.id), output_field=Version._meta.pk, ) else: # We have to use a slow subquery. subquery = self.get_for_model(model, model_db=model_db).exclude( object_id__in=list( model._default_manager.using(model_db).values_list("pk", flat=True).order_by().iterator() ), ).values_list("object_id").annotate( latest_pk=models.Max("pk") ).order_by().values_list("latest_pk", flat=True) # Perform the subquery. return self.filter( pk__in=subquery, ) def get_unique(self): last_key = None for version in self.iterator(): key = (version.object_id, version.content_type_id, version.db, version._local_field_dict) if last_key != key: yield version last_key = key @python_2_unicode_compatible class Version(models.Model): """A saved version of a database model.""" objects = VersionQuerySet.as_manager() revision = models.ForeignKey( Revision, on_delete=models.CASCADE, help_text="The revision that contains this version.", ) object_id = models.CharField( max_length=191, help_text="Primary key of the model under version control.", ) content_type = models.ForeignKey( ContentType, on_delete=models.CASCADE, help_text="Content type of the model under version control.", ) @property def _content_type(self): return ContentType.objects.db_manager(self._state.db).get_for_id(self.content_type_id) @property def _model(self): return self._content_type.model_class() # A link to the current instance, not the version stored in this Version! object = GenericForeignKey( ct_field="content_type", fk_field="object_id", ) db = models.CharField( max_length=191, help_text="The database the model under version control is stored in.", ) format = models.CharField( max_length=255, help_text="The serialization format used by this model.", ) serialized_data = models.TextField( help_text="The serialized form of this version of the model.", ) object_repr = models.TextField( help_text="A string representation of the object.", ) @cached_property def _object_version(self): data = self.serialized_data data = force_text(data.encode("utf8")) try: return list(serializers.deserialize(self.format, data, ignorenonexistent=True))[0] except DeserializationError: raise RevertError(ugettext("Could not load %(object_repr)s version - incompatible version data.") % { "object_repr": self.object_repr, }) except serializers.SerializerDoesNotExist: raise RevertError(ugettext("Could not load %(object_repr)s version - unknown serializer %(format)s.") % { "object_repr": self.object_repr, "format": self.format, }) @cached_property def _local_field_dict(self): """ A dictionary mapping field names to field values in this version of the model. Parent links of inherited multi-table models will not be followed. """ version_options = _get_options(self._model) object_version = self._object_version obj = object_version.object model = self._model field_dict = {} for field_name in version_options.fields: field = model._meta.get_field(field_name) if isinstance(field, models.ManyToManyField): # M2M fields with a custom through are not stored in m2m_data, but as a separate model. if field.attname in object_version.m2m_data: field_dict[field.attname] = object_version.m2m_data[field.attname] else: field_dict[field.attname] = getattr(obj, field.attname) return field_dict @cached_property def field_dict(self): """ A dictionary mapping field names to field values in this version of the model. This method will follow parent links, if present. """ field_dict = self._local_field_dict # Add parent data. for parent_model, field in self._model._meta.concrete_model._meta.parents.items(): content_type = _get_content_type(parent_model, self._state.db) parent_id = field_dict[field.attname] parent_version = self.revision.version_set.get( content_type=content_type, object_id=parent_id, db=self.db, ) field_dict.update(parent_version.field_dict) return field_dict def revert(self): self._object_version.save(using=self.db) def __str__(self): return self.object_repr class Meta: app_label = 'reversion' unique_together = ( ("db", "content_type", "object_id", "revision"), ) ordering = ("-pk",) class _Str(models.Func): """Casts a value to the database's text type.""" function = "CAST" template = "%(function)s(%(expressions)s as %(db_type)s)" def __init__(self, expression): super(_Str, self).__init__(expression, output_field=models.TextField()) def as_sql(self, compiler, connection): self.extra["db_type"] = self.output_field.db_type(connection) return super(_Str, self).as_sql(compiler, connection) def _safe_subquery(method, left_query, left_field_name, right_subquery, right_field_name): right_subquery = right_subquery.order_by().values_list(right_field_name, flat=True) left_field = left_query.model._meta.get_field(left_field_name) right_field = right_subquery.model._meta.get_field(right_field_name) # If the databases don't match, we have to do it in-memory. # If it's not a supported database, we also have to do it in-memory. if ( left_query.db != right_subquery.db or not ( left_field.get_internal_type() != right_field.get_internal_type() and connections[left_query.db].vendor in ("sqlite", "postgresql") ) ): right_subquery = list(right_subquery.iterator()) else: # If the left hand side is not a text field, we need to cast it. if not isinstance(left_field, (models.CharField, models.TextField)): left_field_name_str = "{}_str".format(left_field_name) left_query = left_query.annotate(**{ left_field_name_str: _Str(left_field_name), }) left_field_name = left_field_name_str # If the right hand side is not a text field, we need to cast it. if not isinstance(right_field, (models.CharField, models.TextField)): right_field_name_str = "{}_str".format(right_field_name) right_subquery = right_subquery.annotate(**{ right_field_name_str: _Str(right_field_name), }).values_list(right_field_name_str, flat=True) # All done! return getattr(left_query, method)(**{ "{}__in".format(left_field_name): right_subquery, }) django-reversion-2.0.13/reversion/revisions.py000066400000000000000000000316351323160775000214740ustar00rootroot00000000000000from __future__ import unicode_literals from collections import namedtuple, defaultdict from contextlib import contextmanager from functools import wraps from threading import local from django.apps import apps from django.core import serializers from django.core.exceptions import ObjectDoesNotExist from django.db import models, transaction, router from django.db.models.query import QuerySet from django.db.models.signals import post_save, m2m_changed from django.utils.encoding import force_text from django.utils import timezone, six from reversion.compat import remote_field from reversion.errors import RevisionManagementError, RegistrationError from reversion.signals import pre_revision_commit, post_revision_commit _VersionOptions = namedtuple("VersionOptions", ( "fields", "follow", "format", "for_concrete_model", "ignore_duplicates", )) _StackFrame = namedtuple("StackFrame", ( "manage_manually", "user", "comment", "date_created", "db_versions", "meta", )) class _Local(local): def __init__(self): self.stack = () _local = _Local() def is_active(): return bool(_local.stack) def _current_frame(): if not is_active(): raise RevisionManagementError("There is no active revision for this thread") return _local.stack[-1] def _copy_db_versions(db_versions): return { db: versions.copy() for db, versions in db_versions.items() } def _push_frame(manage_manually, using): if is_active(): current_frame = _current_frame() db_versions = _copy_db_versions(current_frame.db_versions) db_versions.setdefault(using, {}) stack_frame = current_frame._replace( manage_manually=manage_manually, db_versions=db_versions, ) else: stack_frame = _StackFrame( manage_manually=manage_manually, user=None, comment="", date_created=timezone.now(), db_versions={using: {}}, meta=(), ) _local.stack += (stack_frame,) def _update_frame(**kwargs): _local.stack = _local.stack[:-1] + (_current_frame()._replace(**kwargs),) def _pop_frame(): prev_frame = _current_frame() _local.stack = _local.stack[:-1] if is_active(): current_frame = _current_frame() db_versions = { db: prev_frame.db_versions[db] for db in current_frame.db_versions.keys() } _update_frame( user=prev_frame.user, comment=prev_frame.comment, date_created=prev_frame.date_created, db_versions=db_versions, meta=prev_frame.meta, ) def is_manage_manually(): return _current_frame().manage_manually def set_user(user): _update_frame(user=user) def get_user(): return _current_frame().user def set_comment(comment): _update_frame(comment=comment) def get_comment(): return _current_frame().comment def set_date_created(date_created): _update_frame(date_created=date_created) def get_date_created(): return _current_frame().date_created def add_meta(model, **values): _update_frame(meta=_current_frame().meta + ((model, values),)) def _follow_relations(obj): version_options = _get_options(obj.__class__) for follow_name in version_options.follow: try: follow_obj = getattr(obj, follow_name) except ObjectDoesNotExist: continue if isinstance(follow_obj, models.Model): yield follow_obj elif isinstance(follow_obj, (models.Manager, QuerySet)): for follow_obj_instance in follow_obj.all(): yield follow_obj_instance elif follow_obj is not None: raise RegistrationError("{name}.{follow_name} should be a Model or QuerySet".format( name=obj.__class__.__name__, follow_name=follow_name, )) def _follow_relations_recursive(obj): def do_follow(obj): if obj not in relations: relations.add(obj) for related in _follow_relations(obj): do_follow(related) relations = set() do_follow(obj) return relations def _add_to_revision(obj, using, model_db, explicit): from reversion.models import Version # Exit early if the object is not fully-formed. if obj.pk is None: return version_options = _get_options(obj.__class__) content_type = _get_content_type(obj.__class__, using) object_id = force_text(obj.pk) version_key = (content_type, object_id) # If the obj is already in the revision, stop now. db_versions = _current_frame().db_versions versions = db_versions[using] if version_key in versions and not explicit: return # Get the version data. version = Version( content_type=content_type, object_id=object_id, db=model_db, format=version_options.format, serialized_data=serializers.serialize( version_options.format, (obj,), fields=version_options.fields, ), object_repr=force_text(obj), ) # If the version is a duplicate, stop now. if version_options.ignore_duplicates and explicit: previous_version = Version.objects.using(using).get_for_object(obj, model_db=model_db).first() if previous_version and previous_version._local_field_dict == version._local_field_dict: return # Store the version. db_versions = _copy_db_versions(db_versions) db_versions[using][version_key] = version _update_frame(db_versions=db_versions) # Follow relations. for follow_obj in _follow_relations(obj): _add_to_revision(follow_obj, using, model_db, False) def add_to_revision(obj, model_db=None): model_db = model_db or router.db_for_write(obj.__class__, instance=obj) for db in _current_frame().db_versions.keys(): _add_to_revision(obj, db, model_db, True) def _save_revision(versions, user=None, comment="", meta=(), date_created=None, using=None): from reversion.models import Revision # Only save versions that exist in the database. model_db_pks = defaultdict(lambda: defaultdict(set)) for version in versions: model_db_pks[version._model][version.db].add(version.object_id) model_db_existing_pks = { model: { db: frozenset(map( force_text, model._default_manager.using(db).filter(pk__in=pks).values_list("pk", flat=True), )) for db, pks in db_pks.items() } for model, db_pks in model_db_pks.items() } versions = [ version for version in versions if version.object_id in model_db_existing_pks[version._model][version.db] ] # Bail early if there are no objects to save. if not versions: return # Save a new revision. revision = Revision( date_created=date_created, user=user, comment=comment, ) # Send the pre_revision_commit signal. pre_revision_commit.send( sender=create_revision, revision=revision, versions=versions, ) # Save the revision. revision.save(using=using) # Save version models. for version in versions: version.revision = revision version.save(using=using) # Save the meta information. for meta_model, meta_fields in meta: meta_model._default_manager.db_manager(using=using).create( revision=revision, **meta_fields ) # Send the post_revision_commit signal. post_revision_commit.send( sender=create_revision, revision=revision, versions=versions, ) @contextmanager def _dummy_context(): yield @contextmanager def _create_revision_context(manage_manually, using, atomic): _push_frame(manage_manually, using) try: context = transaction.atomic(using=using) if atomic else _dummy_context() with context: yield # Only save for a db if that's the last stack frame for that db. if not any(using in frame.db_versions for frame in _local.stack[:-1]): current_frame = _current_frame() _save_revision( versions=current_frame.db_versions[using].values(), user=current_frame.user, comment=current_frame.comment, meta=current_frame.meta, date_created=current_frame.date_created, using=using, ) finally: _pop_frame() def create_revision(manage_manually=False, using=None, atomic=True): from reversion.models import Revision using = using or router.db_for_write(Revision) return _ContextWrapper(_create_revision_context, (manage_manually, using, atomic)) class _ContextWrapper(object): def __init__(self, func, args): self._func = func self._args = args self._context = func(*args) def __enter__(self): return self._context.__enter__() def __exit__(self, exc_type, exc_value, traceback): return self._context.__exit__(exc_type, exc_value, traceback) def __call__(self, func): @wraps(func) def do_revision_context(*args, **kwargs): with self._func(*self._args): return func(*args, **kwargs) return do_revision_context def _post_save_receiver(sender, instance, using, **kwargs): if is_registered(sender) and is_active() and not is_manage_manually(): add_to_revision(instance, model_db=using) def _m2m_changed_receiver(instance, using, action, model, reverse, **kwargs): if action.startswith("post_") and not reverse: if is_registered(instance) and is_active() and not is_manage_manually(): add_to_revision(instance, model_db=using) def _get_registration_key(model): return (model._meta.app_label, model._meta.model_name) _registered_models = {} def is_registered(model): return _get_registration_key(model) in _registered_models def get_registered_models(): return (apps.get_model(*key) for key in _registered_models.keys()) def _get_senders_and_signals(model): yield model, post_save, _post_save_receiver opts = model._meta.concrete_model._meta for field in opts.local_many_to_many: m2m_model = remote_field(field).through if isinstance(m2m_model, six.string_types): if "." not in m2m_model: m2m_model = "{app_label}.{m2m_model}".format( app_label=opts.app_label, m2m_model=m2m_model ) yield m2m_model, m2m_changed, _m2m_changed_receiver def register(model=None, fields=None, exclude=(), follow=(), format="json", for_concrete_model=True, ignore_duplicates=False): def register(model): # Prevent multiple registration. if is_registered(model): raise RegistrationError("{model} has already been registered with django-reversion".format( model=model, )) # Parse fields. opts = model._meta.concrete_model._meta version_options = _VersionOptions( fields=tuple( field_name for field_name in ([ field.name for field in opts.local_fields + opts.local_many_to_many ] if fields is None else fields) if field_name not in exclude ), follow=tuple(follow), format=format, for_concrete_model=for_concrete_model, ignore_duplicates=ignore_duplicates, ) # Register the model. _registered_models[_get_registration_key(model)] = version_options # Connect signals. for sender, signal, signal_receiver in _get_senders_and_signals(model): signal.connect(signal_receiver, sender=sender) # All done! return model # Return a class decorator if model is not given if model is None: return register # Register the model. return register(model) def _assert_registered(model): if not is_registered(model): raise RegistrationError("{model} has not been registered with django-reversion".format( model=model, )) def _get_options(model): _assert_registered(model) return _registered_models[_get_registration_key(model)] def unregister(model): _assert_registered(model) del _registered_models[_get_registration_key(model)] # Disconnect signals. for sender, signal, signal_receiver in _get_senders_and_signals(model): signal.disconnect(signal_receiver, sender=sender) def _get_content_type(model, using): from django.contrib.contenttypes.models import ContentType version_options = _get_options(model) return ContentType.objects.db_manager(using).get_for_model( model, for_concrete_model=version_options.for_concrete_model, ) django-reversion-2.0.13/reversion/signals.py000066400000000000000000000003311323160775000211000ustar00rootroot00000000000000from django.dispatch.dispatcher import Signal _signal_args = [ "revision", "versions", ] pre_revision_commit = Signal(providing_args=_signal_args) post_revision_commit = Signal(providing_args=_signal_args) django-reversion-2.0.13/reversion/templates/000077500000000000000000000000001323160775000210675ustar00rootroot00000000000000django-reversion-2.0.13/reversion/templates/reversion/000077500000000000000000000000001323160775000231035ustar00rootroot00000000000000django-reversion-2.0.13/reversion/templates/reversion/change_list.html000066400000000000000000000006531323160775000262550ustar00rootroot00000000000000{% extends "admin/change_list.html" %} {% load i18n admin_urls %} {% block object-tools-items %} {% if not is_popup and has_add_permission and has_change_permission %}
  • {% blocktrans with cl.opts.verbose_name_plural|escape as name %}Recover deleted {{name}}{% endblocktrans %}
  • {% endif %} {{block.super}} {% endblock %} django-reversion-2.0.13/reversion/templates/reversion/object_history.html000066400000000000000000000035571323160775000270320ustar00rootroot00000000000000{% extends "admin/object_history.html" %} {% load i18n %} {% block content %}

    {% blocktrans %}Choose a date from the list below to revert to a previous version of this object.{% endblocktrans %}

    {% if action_list %} {% for action in action_list %} {% endfor %}
    {% trans 'Date/time' %} {% trans 'User' %} {% trans 'Action' %}
    {{action.revision.date_created|date:"DATETIME_FORMAT"}} {% if action.revision.user %} {{action.revision.user.get_username}} {% if action.revision.user.get_full_name %} ({{action.revision.user.get_full_name}}){% endif %} {% else %} — {% endif %} {{action.revision.comment|linebreaksbr|default:""}}
    {% else %}

    {% trans "This object doesn't have a change history. It probably wasn't added via this admin site." %}

    {% endif %}
    {% endblock %} django-reversion-2.0.13/reversion/templates/reversion/recover_form.html000066400000000000000000000017741323160775000264720ustar00rootroot00000000000000{% extends "reversion/revision_form.html" %} {% load i18n admin_urls %} {% block breadcrumbs %} {% endblock %} {% block object-tools %}{% endblock %} {% block form_top %}

    {% blocktrans %}Press the save button below to recover this version of the object.{% endblocktrans %}

    {% endblock %} {% block submit_buttons_top %}{% with is_popup=1 %}{{block.super}}{% endwith %}{% endblock %} {% block submit_buttons_bottom %}{% with is_popup=1 %}{{block.super}}{% endwith %}{% endblock %} django-reversion-2.0.13/reversion/templates/reversion/recover_list.html000066400000000000000000000033461323160775000264770ustar00rootroot00000000000000{% extends "admin/base_site.html" %} {% load i18n l10n admin_urls %} {% block breadcrumbs %} {% endblock %} {% block content %}

    {% blocktrans %}Choose a date from the list below to recover a deleted version of an object.{% endblocktrans %}

    {% if deleted %} {% for deletion in deleted %} {% endfor %}
    {% trans 'Date/time' %} {{opts.verbose_name|capfirst}}
    {{deletion.revision.date_created}} {{deletion.object_repr}}
    {% else %}

    {% trans "There are no deleted objects to recover." %}

    {% endif %}
    {% endblock %} django-reversion-2.0.13/reversion/templates/reversion/revision_form.html000066400000000000000000000021711323160775000266530ustar00rootroot00000000000000{% extends "admin/change_form.html" %} {% load i18n admin_urls %} {% block breadcrumbs %} {% endblock %} {% block object-tools %}{% endblock %} {% block form_top %}

    {% blocktrans %}Press the save button below to revert to this version of the object.{% endblocktrans %}

    {% endblock %} {% block submit_buttons_top %}{% with is_popup=1 %}{{block.super}}{% endwith %}{% endblock %} {% block submit_buttons_bottom %}{% with is_popup=1 %}{{block.super}}{% endwith %}{% endblock %} django-reversion-2.0.13/reversion/views.py000066400000000000000000000042511323160775000206020ustar00rootroot00000000000000from functools import wraps from reversion.compat import is_authenticated from reversion.revisions import create_revision as create_revision_base, set_user, get_user class _RollBackRevisionView(Exception): def __init__(self, response): self.response = response def _request_creates_revision(request): return request.method not in ("OPTIONS", "GET", "HEAD") def _set_user_from_request(request): if getattr(request, "user", None) and is_authenticated(request.user) and get_user() is None: set_user(request.user) def create_revision(manage_manually=False, using=None, atomic=True): """ View decorator that wraps the request in a revision. The revision will have it's user set from the request automatically. """ def decorator(func): @wraps(func) def do_revision_view(request, *args, **kwargs): if _request_creates_revision(request): try: with create_revision_base(manage_manually=manage_manually, using=using, atomic=atomic): response = func(request, *args, **kwargs) # Check for an error response. if response.status_code >= 400: raise _RollBackRevisionView(response) # Otherwise, we're good. _set_user_from_request(request) return response except _RollBackRevisionView as ex: return ex.response return func(request, *args, **kwargs) return do_revision_view return decorator class RevisionMixin(object): """ A class-based view mixin that wraps the request in a revision. The revision will have it's user set from the request automatically. """ revision_manage_manually = False revision_using = None revision_atomic = True def __init__(self, *args, **kwargs): super(RevisionMixin, self).__init__(*args, **kwargs) self.dispatch = create_revision( manage_manually=self.revision_manage_manually, using=self.revision_using, atomic=self.revision_atomic )(self.dispatch) django-reversion-2.0.13/setup.cfg000066400000000000000000000001221323160775000166710ustar00rootroot00000000000000[bdist_wheel] universal = 1 [flake8] max-line-length=120 exclude=venv,migrations django-reversion-2.0.13/setup.py000066400000000000000000000027031323160775000165710ustar00rootroot00000000000000from setuptools import setup, find_packages from reversion import __version__ # Load in babel support, if available. try: from babel.messages import frontend as babel cmdclass = { "compile_catalog": babel.compile_catalog, "extract_messages": babel.extract_messages, "init_catalog": babel.init_catalog, "update_catalog": babel.update_catalog, } except ImportError: cmdclass = {} setup( name="django-reversion", version='.'.join(str(x) for x in __version__), license="BSD", description="An extension to the Django web framework that provides version control for model instances.", author="Dave Hall", author_email="dave@etianen.com", url="http://github.com/etianen/django-reversion", zip_safe=False, packages=find_packages(), package_data={ "reversion": ["locale/*/LC_MESSAGES/django.*", "templates/reversion/*.html"]}, cmdclass=cmdclass, install_requires=[ "django>=1.8", ], classifiers=[ "Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Intended Audience :: Developers", "License :: OSI Approved :: BSD License", "Operating System :: OS Independent", "Programming Language :: Python", 'Programming Language :: Python :: 2.7', 'Programming Language :: Python :: 3.4', 'Programming Language :: Python :: 3.5', "Framework :: Django", ] ) django-reversion-2.0.13/tests/000077500000000000000000000000001323160775000162175ustar00rootroot00000000000000django-reversion-2.0.13/tests/manage.py000077500000000000000000000014621323160775000200270ustar00rootroot00000000000000#!/usr/bin/env python import os import sys if __name__ == "__main__": os.environ.setdefault("DJANGO_SETTINGS_MODULE", "test_project.settings") try: from django.core.management import execute_from_command_line except ImportError: # The above import may fail for some other reason. Ensure that the # issue is really that Django is missing to avoid masking other # exceptions on Python 2. try: import django # noqa except ImportError: raise ImportError( "Couldn't import Django. Are you sure it's installed and " "available on your PYTHONPATH environment variable? Did you " "forget to activate a virtual environment?" ) raise execute_from_command_line(sys.argv) django-reversion-2.0.13/tests/test_app/000077500000000000000000000000001323160775000200365ustar00rootroot00000000000000django-reversion-2.0.13/tests/test_app/__init__.py000066400000000000000000000000001323160775000221350ustar00rootroot00000000000000django-reversion-2.0.13/tests/test_app/admin.py000066400000000000000000000004711323160775000215020ustar00rootroot00000000000000from django.contrib import admin from reversion.admin import VersionAdmin from test_app.models import TestModel, TestModelRelated class TestModelAdmin(VersionAdmin): filter_horizontal = ("related",) admin.site.register(TestModel, TestModelAdmin) admin.site.register(TestModelRelated, admin.ModelAdmin) django-reversion-2.0.13/tests/test_app/migrations/000077500000000000000000000000001323160775000222125ustar00rootroot00000000000000django-reversion-2.0.13/tests/test_app/migrations/0001_initial.py000066400000000000000000000105101323160775000246520ustar00rootroot00000000000000# -*- coding: utf-8 -*- # Generated by Django 1.9.7 on 2016-06-14 10:27 from __future__ import unicode_literals from django.db import migrations, models import django.db.models.deletion class Migration(migrations.Migration): initial = True dependencies = [ ('contenttypes', '0002_remove_content_type_name'), ('reversion', '0001_squashed_0004_auto_20160611_1202'), ] operations = [ migrations.CreateModel( name='TestMeta', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(max_length=191)), ('revision', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='reversion.Revision')), ], ), migrations.CreateModel( name='TestModel', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(default='v1', max_length=191)), ], ), migrations.CreateModel( name='TestModelGenericInline', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('object_id', models.IntegerField()), ('inline_name', models.CharField(default='v1', max_length=191)), ('content_type', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='contenttypes.ContentType')), ], ), migrations.CreateModel( name='TestModelInline', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('inline_name', models.CharField(default='v1', max_length=191)), ], ), migrations.CreateModel( name='TestModelRelated', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(default='v1', max_length=191)), ], ), migrations.CreateModel( name='TestModelThrough', fields=[ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), ('name', models.CharField(default='v1', max_length=191)), ], ), migrations.CreateModel( name='TestModelParent', fields=[ ('testmodel_ptr', models.OneToOneField(auto_created=True, on_delete=django.db.models.deletion.CASCADE, parent_link=True, primary_key=True, serialize=False, to='test_app.TestModel')), ('parent_name', models.CharField(default='parent v1', max_length=191)), ], bases=('test_app.testmodel',), ), migrations.CreateModel( name='TestModelEscapePK', fields=[ ('name', models.CharField(max_length=191, primary_key=True, serialize=False)), ], ), migrations.AddField( model_name='testmodelthrough', name='test_model', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='test_app.TestModel'), ), migrations.AddField( model_name='testmodelthrough', name='test_model_related', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='+', to='test_app.TestModelRelated'), ), migrations.AddField( model_name='testmodelinline', name='test_model', field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='test_app.TestModel'), ), migrations.AddField( model_name='testmodel', name='related', field=models.ManyToManyField(blank=True, related_name='_testmodel_related_+', to='test_app.TestModelRelated'), ), migrations.AddField( model_name='testmodel', name='related_through', field=models.ManyToManyField(blank=True, related_name='_testmodel_related_through_+', through='test_app.TestModelThrough', to='test_app.TestModelRelated'), ), ] django-reversion-2.0.13/tests/test_app/migrations/__init__.py000066400000000000000000000000001323160775000243110ustar00rootroot00000000000000django-reversion-2.0.13/tests/test_app/models.py000066400000000000000000000042351323160775000216770ustar00rootroot00000000000000from django.db import models from django.contrib.contenttypes.models import ContentType try: from django.contrib.contenttypes.fields import GenericRelation except ImportError: # Django < 1.9 pragma: no cover from django.contrib.contenttypes.generic import GenericRelation from reversion.models import Revision class TestModelGenericInline(models.Model): object_id = models.IntegerField() content_type = models.ForeignKey( ContentType, on_delete=models.CASCADE, ) inline_name = models.CharField( max_length=191, default="v1", ) class TestModel(models.Model): name = models.CharField( max_length=191, default="v1", ) related = models.ManyToManyField( "TestModelRelated", blank=True, related_name="+", ) related_through = models.ManyToManyField( "TestModelRelated", blank=True, through="TestModelThrough", related_name="+", ) generic_inlines = GenericRelation(TestModelGenericInline) class TestModelEscapePK(models.Model): name = models.CharField(max_length=191, primary_key=True) class TestModelThrough(models.Model): test_model = models.ForeignKey( "TestModel", related_name="+", on_delete=models.CASCADE, ) test_model_related = models.ForeignKey( "TestModelRelated", related_name="+", on_delete=models.CASCADE, ) name = models.CharField( max_length=191, default="v1", ) class TestModelRelated(models.Model): name = models.CharField( max_length=191, default="v1", ) class TestModelParent(TestModel): parent_name = models.CharField( max_length=191, default="parent v1", ) class TestModelInline(models.Model): test_model = models.ForeignKey( TestModel, on_delete=models.CASCADE, ) inline_name = models.CharField( max_length=191, default="v1", ) class TestMeta(models.Model): revision = models.ForeignKey( Revision, on_delete=models.CASCADE, ) name = models.CharField( max_length=191, ) django-reversion-2.0.13/tests/test_app/tests/000077500000000000000000000000001323160775000212005ustar00rootroot00000000000000django-reversion-2.0.13/tests/test_app/tests/__init__.py000066400000000000000000000000001323160775000232770ustar00rootroot00000000000000django-reversion-2.0.13/tests/test_app/tests/base.py000066400000000000000000000072351323160775000224730ustar00rootroot00000000000000from datetime import timedelta from django.conf import settings from django.contrib.auth.models import User from django.core.management import call_command try: from django.urls import clear_url_caches except ImportError: # Django < 1.10 pragma: no cover from django.core.urlresolvers import clear_url_caches from django.test import TestCase, TransactionTestCase from django.test.utils import override_settings from django.utils import timezone from django.utils.six import StringIO, assertRegex import reversion from reversion.models import Revision, Version from test_app.models import TestModel, TestModelParent from importlib import import_module try: from importlib import reload except ImportError: # Python 2.7 pass # Test helpers. class TestBaseMixin(object): multi_db = True def reloadUrls(self): reload(import_module(settings.ROOT_URLCONF)) clear_url_caches() def setUp(self): super(TestBaseMixin, self).setUp() for model in list(reversion.get_registered_models()): reversion.unregister(model) def tearDown(self): super(TestBaseMixin, self).tearDown() for model in list(reversion.get_registered_models()): reversion.unregister(model) def callCommand(self, command, *args, **kwargs): kwargs.setdefault("stdout", StringIO()) kwargs.setdefault("stderr", StringIO()) kwargs.setdefault("verbosity", 2) return call_command(command, *args, **kwargs) def assertSingleRevision(self, objects, user=None, comment="", meta_names=(), date_created=None, using=None, model_db=None): revision = Version.objects.using(using).get_for_object(objects[0], model_db=model_db).get().revision self.assertEqual(revision.user, user) if hasattr(comment, 'pattern'): assertRegex(self, revision.comment, comment) elif comment is not None: # Allow a wildcard comment. self.assertEqual(revision.comment, comment) self.assertAlmostEqual(revision.date_created, date_created or timezone.now(), delta=timedelta(seconds=1)) # Check meta. self.assertEqual(revision.testmeta_set.count(), len(meta_names)) for meta_name in meta_names: self.assertTrue(revision.testmeta_set.filter(name=meta_name).exists()) # Check objects. self.assertEqual(revision.version_set.count(), len(objects)) for obj in objects: self.assertTrue(Version.objects.using(using).get_for_object( obj, model_db=model_db, ).filter( revision=revision, ).exists()) def assertNoRevision(self, using=None): self.assertEqual(Revision.objects.using(using).all().count(), 0) class TestBase(TestBaseMixin, TestCase): pass class TestBaseTransaction(TestBaseMixin, TransactionTestCase): pass class TestModelMixin(object): def setUp(self): super(TestModelMixin, self).setUp() reversion.register(TestModel) class TestModelParentMixin(TestModelMixin): def setUp(self): super(TestModelParentMixin, self).setUp() reversion.register(TestModelParent, follow=("testmodel_ptr",)) @override_settings(PASSWORD_HASHERS=["django.contrib.auth.hashers.MD5PasswordHasher"]) class UserMixin(TestBase): def setUp(self): super(UserMixin, self).setUp() self.user = User(username="test", is_staff=True, is_superuser=True) self.user.set_password("password") self.user.save() class LoginMixin(UserMixin): def setUp(self): super(LoginMixin, self).setUp() self.client.login(username="test", password="password") django-reversion-2.0.13/tests/test_app/tests/test_admin.py000066400000000000000000000213271323160775000237060ustar00rootroot00000000000000import re from django.contrib import admin try: from django.contrib.contenttypes.admin import GenericTabularInline except ImportError: # Django < 1.9 pragma: no cover from django.contrib.contenttypes.generic import GenericTabularInline from django.shortcuts import resolve_url import reversion from reversion.admin import VersionAdmin from reversion.models import Version from test_app.models import TestModel, TestModelParent, TestModelInline, TestModelGenericInline, TestModelEscapePK from test_app.tests.base import TestBase, LoginMixin class AdminMixin(TestBase): def setUp(self): super(AdminMixin, self).setUp() admin.site.register(TestModelParent, VersionAdmin) self.reloadUrls() def tearDown(self): super(AdminMixin, self).tearDown() admin.site.unregister(TestModelParent) self.reloadUrls() class AdminRegisterTest(AdminMixin, TestBase): def setAutoRegister(self): self.assertTrue(reversion.is_registered(TestModelParent)) def setAutoRegisterFollowsParent(self): self.assertTrue(reversion.is_registered(TestModel)) class AdminAddViewTest(LoginMixin, AdminMixin, TestBase): def testAddView(self): self.client.post(resolve_url("admin:test_app_testmodelparent_add"), { "name": "v1", "parent_name": "parent_v1", }) obj = TestModelParent.objects.get() self.assertSingleRevision( (obj, obj.testmodel_ptr), user=self.user, # Django 1.8 gives "Initial version.", Django > 1.8 "Added." comment=re.compile(r"(Initial version\.|Added\.)") ) class AdminUpdateViewTest(LoginMixin, AdminMixin, TestBase): def testUpdateView(self): obj = TestModelParent.objects.create() self.client.post(resolve_url("admin:test_app_testmodelparent_change", obj.pk), { "name": "v2", "parent_name": "parent v2", }) self.assertSingleRevision( (obj, obj.testmodel_ptr), user=self.user, comment="Changed name and parent_name." ) class AdminChangelistView(LoginMixin, AdminMixin, TestBase): def testChangelistView(self): obj = TestModelParent.objects.create() response = self.client.get(resolve_url("admin:test_app_testmodelparent_changelist")) self.assertContains(response, resolve_url("admin:test_app_testmodelparent_change", obj.pk)) class AdminRevisionViewTest(LoginMixin, AdminMixin, TestBase): def setUp(self): super(AdminRevisionViewTest, self).setUp() with reversion.create_revision(): self.obj = TestModelParent.objects.create() with reversion.create_revision(): self.obj.name = "v2" self.obj.parent_name = "parent v2" self.obj.save() def testRevisionView(self): response = self.client.get(resolve_url( "admin:test_app_testmodelparent_revision", self.obj.pk, Version.objects.get_for_object(self.obj)[1].pk, )) self.assertContains(response, 'value="v1"') self.assertContains(response, 'value="parent v1"') # Test that the changes were rolled back. self.obj.refresh_from_db() self.assertEqual(self.obj.name, "v2") self.assertEqual(self.obj.parent_name, "parent v2") self.assertIn("revert", response.context) self.assertTrue(response.context["revert"]) def testRevisionViewOldRevision(self): response = self.client.get(resolve_url( "admin:test_app_testmodelparent_revision", self.obj.pk, Version.objects.get_for_object(self.obj)[0].pk, )) self.assertContains(response, 'value="v2"') self.assertContains(response, 'value="parent v2"') def testRevisionViewRevertError(self): Version.objects.get_for_object(self.obj).update(format="boom") response = self.client.get(resolve_url( "admin:test_app_testmodelparent_revision", self.obj.pk, Version.objects.get_for_object(self.obj)[1].pk, )) self.assertEqual( response["Location"].replace("http://testserver", ""), resolve_url("admin:test_app_testmodelparent_changelist"), ) def testRevisionViewRevert(self): self.client.post(resolve_url( "admin:test_app_testmodelparent_revision", self.obj.pk, Version.objects.get_for_object(self.obj)[1].pk, ), { "name": "v1", "parent_name": "parent v1", }) self.obj.refresh_from_db() self.assertEqual(self.obj.name, "v1") self.assertEqual(self.obj.parent_name, "parent v1") class AdminRecoverViewTest(LoginMixin, AdminMixin, TestBase): def setUp(self): super(AdminRecoverViewTest, self).setUp() with reversion.create_revision(): obj = TestModelParent.objects.create() obj.delete() def testRecoverView(self): response = self.client.get(resolve_url( "admin:test_app_testmodelparent_recover", Version.objects.get_for_model(TestModelParent).get().pk, )) self.assertContains(response, 'value="v1"') self.assertContains(response, 'value="parent v1"') self.assertIn("recover", response.context) self.assertTrue(response.context["recover"]) def testRecoverViewRecover(self): self.client.post(resolve_url( "admin:test_app_testmodelparent_recover", Version.objects.get_for_model(TestModelParent).get().pk, ), { "name": "v1", "parent_name": "parent v1", }) obj = TestModelParent.objects.get() self.assertEqual(obj.name, "v1") self.assertEqual(obj.parent_name, "parent v1") class AdminRecoverlistViewTest(LoginMixin, AdminMixin, TestBase): def testRecoverlistView(self): with reversion.create_revision(): obj = TestModelParent.objects.create() obj.delete() response = self.client.get(resolve_url("admin:test_app_testmodelparent_recoverlist")) self.assertContains(response, resolve_url( "admin:test_app_testmodelparent_recover", Version.objects.get_for_model(TestModelParent).get().pk, )) class AdminHistoryViewTest(LoginMixin, AdminMixin, TestBase): def testHistorylistView(self): with reversion.create_revision(): obj = TestModelParent.objects.create() response = self.client.get(resolve_url("admin:test_app_testmodelparent_history", obj.pk)) self.assertContains(response, resolve_url( "admin:test_app_testmodelparent_revision", obj.pk, Version.objects.get_for_model(TestModelParent).get().pk, )) class AdminQuotingTest(LoginMixin, AdminMixin, TestBase): def setUp(self): super(AdminQuotingTest, self).setUp() admin.site.register(TestModelEscapePK, VersionAdmin) self.reloadUrls() def tearDown(self): super(AdminQuotingTest, self).tearDown() admin.site.unregister(TestModelEscapePK) self.reloadUrls() def testHistoryWithQuotedPrimaryKey(self): pk = 'ABC_123' quoted_pk = admin.utils.quote(pk) # test is invalid if quoting does not change anything assert quoted_pk != pk with reversion.create_revision(): obj = TestModelEscapePK.objects.create(name=pk) revision_url = resolve_url( "admin:test_app_testmodelescapepk_revision", quoted_pk, Version.objects.get_for_object(obj).get().pk, ) history_url = resolve_url( "admin:test_app_testmodelescapepk_history", quoted_pk ) response = self.client.get(history_url) self.assertContains(response, revision_url) response = self.client.get(revision_url) self.assertContains(response, 'value="{}"'.format(pk)) class TestModelInlineAdmin(admin.TabularInline): model = TestModelInline class TestModelGenericInlineAdmin(GenericTabularInline): model = TestModelGenericInline class TestModelParentAdmin(VersionAdmin): inlines = (TestModelInlineAdmin, TestModelGenericInlineAdmin) class AdminRegisterInlineTest(TestBase): def setUp(self): super(AdminRegisterInlineTest, self).setUp() admin.site.register(TestModelParent, TestModelParentAdmin) self.reloadUrls() def tearDown(self): super(AdminRegisterInlineTest, self).tearDown() admin.site.unregister(TestModelParent) self.reloadUrls() def testAutoRegisterInline(self): self.assertTrue(reversion.is_registered(TestModelInline)) def testAutoRegisterGenericInline(self): self.assertTrue(reversion.is_registered(TestModelGenericInline)) django-reversion-2.0.13/tests/test_app/tests/test_api.py000066400000000000000000000260201323160775000233620ustar00rootroot00000000000000from datetime import timedelta from django.contrib.auth.models import User from django.db import models from django.db.transaction import get_connection from django.utils import timezone import reversion from test_app.models import TestModel, TestModelRelated, TestModelThrough, TestModelParent, TestMeta from test_app.tests.base import TestBase, TestBaseTransaction, TestModelMixin, UserMixin try: from unittest.mock import MagicMock except ImportError: from mock import MagicMock class SaveTest(TestModelMixin, TestBase): def testModelSave(self): TestModel.objects.create() self.assertNoRevision() class IsRegisteredTest(TestModelMixin, TestBase): def testIsRegistered(self): self.assertTrue(reversion.is_registered(TestModel)) class IsRegisterUnregisteredTest(TestBase): def testIsRegisteredFalse(self): self.assertFalse(reversion.is_registered(TestModel)) class GetRegisteredModelsTest(TestModelMixin, TestBase): def testGetRegisteredModels(self): self.assertEqual(set(reversion.get_registered_models()), set((TestModel,))) class RegisterTest(TestBase): def testRegister(self): reversion.register(TestModel) self.assertTrue(reversion.is_registered(TestModel)) def testRegisterDecorator(self): @reversion.register() class TestModelDecorater(models.Model): pass self.assertTrue(reversion.is_registered(TestModelDecorater)) def testRegisterAlreadyRegistered(self): reversion.register(TestModel) with self.assertRaises(reversion.RegistrationError): reversion.register(TestModel) def testRegisterM2MSThroughLazy(self): # When register is used as a decorator in models.py, lazy relations haven't had a chance to be resolved, so # will still be a string. @reversion.register() class TestModelLazy(models.Model): related = models.ManyToManyField( TestModelRelated, through="TestModelThroughLazy", ) class TestModelThroughLazy(models.Model): pass class UnregisterTest(TestModelMixin, TestBase): def testUnregister(self): reversion.unregister(TestModel) self.assertFalse(reversion.is_registered(TestModel)) class UnregisterUnregisteredTest(TestBase): def testUnregisterNotRegistered(self): with self.assertRaises(reversion.RegistrationError): reversion.unregister(User) class CreateRevisionTest(TestModelMixin, TestBase): def testCreateRevision(self): with reversion.create_revision(): obj = TestModel.objects.create() self.assertSingleRevision((obj,)) def testCreateRevisionNested(self): with reversion.create_revision(): with reversion.create_revision(): obj = TestModel.objects.create() self.assertSingleRevision((obj,)) def testCreateRevisionEmpty(self): with reversion.create_revision(): pass self.assertNoRevision() def testCreateRevisionException(self): try: with reversion.create_revision(): TestModel.objects.create() raise Exception("Boom!") except Exception: pass self.assertNoRevision() def testCreateRevisionDecorator(self): obj = reversion.create_revision()(TestModel.objects.create)() self.assertSingleRevision((obj,)) def testPreRevisionCommitSignal(self): _callback = MagicMock() reversion.signals.pre_revision_commit.connect(_callback) with reversion.create_revision(): TestModel.objects.create() self.assertEqual(_callback.call_count, 1) def testPostRevisionCommitSignal(self): _callback = MagicMock() reversion.signals.post_revision_commit.connect(_callback) with reversion.create_revision(): TestModel.objects.create() self.assertEqual(_callback.call_count, 1) class CreateRevisionAtomicTest(TestModelMixin, TestBaseTransaction): def testCreateRevisionAtomic(self): self.assertFalse(get_connection().in_atomic_block) with reversion.create_revision(): self.assertTrue(get_connection().in_atomic_block) def testCreateRevisionNonAtomic(self): self.assertFalse(get_connection().in_atomic_block) with reversion.create_revision(atomic=False): self.assertFalse(get_connection().in_atomic_block) class CreateRevisionManageManuallyTest(TestModelMixin, TestBase): def testCreateRevisionManageManually(self): with reversion.create_revision(manage_manually=True): TestModel.objects.create() self.assertNoRevision() def testCreateRevisionManageManuallyNested(self): with reversion.create_revision(): with reversion.create_revision(manage_manually=True): TestModel.objects.create() self.assertNoRevision() class CreateRevisionDbTest(TestModelMixin, TestBase): def testCreateRevisionMultiDb(self): with reversion.create_revision(using="mysql"), reversion.create_revision(using="postgres"): obj = TestModel.objects.create() self.assertNoRevision() self.assertSingleRevision((obj,), using="mysql") self.assertSingleRevision((obj,), using="postgres") class CreateRevisionFollowTest(TestBase): def testCreateRevisionFollow(self): reversion.register(TestModel, follow=("related",)) reversion.register(TestModelRelated) obj_related = TestModelRelated.objects.create() with reversion.create_revision(): obj = TestModel.objects.create() obj.related.add(obj_related) self.assertSingleRevision((obj, obj_related)) def testCreateRevisionFollowThrough(self): reversion.register(TestModel, follow=("related_through",)) reversion.register(TestModelThrough, follow=("test_model", "test_model_related",)) reversion.register(TestModelRelated) obj_related = TestModelRelated.objects.create() with reversion.create_revision(): obj = TestModel.objects.create() obj_through = TestModelThrough.objects.create( test_model=obj, test_model_related=obj_related, ) self.assertSingleRevision((obj, obj_through, obj_related)) def testCreateRevisionFollowInvalid(self): reversion.register(TestModel, follow=("name",)) with reversion.create_revision(): with self.assertRaises(reversion.RegistrationError): TestModel.objects.create() class CreateRevisionIgnoreDuplicatesTest(TestBase): def testCreateRevisionIgnoreDuplicates(self): reversion.register(TestModel, ignore_duplicates=True) with reversion.create_revision(): obj = TestModel.objects.create() with reversion.create_revision(): obj.save() self.assertSingleRevision((obj,)) class CreateRevisionInheritanceTest(TestModelMixin, TestBase): def testCreateRevisionInheritance(self): reversion.register(TestModelParent, follow=("testmodel_ptr",)) with reversion.create_revision(): obj = TestModelParent.objects.create() self.assertSingleRevision((obj, obj.testmodel_ptr)) class SetCommentTest(TestModelMixin, TestBase): def testSetComment(self): with reversion.create_revision(): reversion.set_comment("comment v1") obj = TestModel.objects.create() self.assertSingleRevision((obj,), comment="comment v1") def testSetCommentNoBlock(self): with self.assertRaises(reversion.RevisionManagementError): reversion.set_comment("comment v1") class GetCommentTest(TestBase): def testGetComment(self): with reversion.create_revision(): reversion.set_comment("comment v1") self.assertEqual(reversion.get_comment(), "comment v1") def testGetCommentDefault(self): with reversion.create_revision(): self.assertEqual(reversion.get_comment(), "") def testGetCommentNoBlock(self): with self.assertRaises(reversion.RevisionManagementError): reversion.get_comment() class SetUserTest(UserMixin, TestModelMixin, TestBase): def testSetUser(self): with reversion.create_revision(): reversion.set_user(self.user) obj = TestModel.objects.create() self.assertSingleRevision((obj,), user=self.user) def testSetUserNoBlock(self): with self.assertRaises(reversion.RevisionManagementError): reversion.set_user(self.user) class GetUserTest(UserMixin, TestBase): def testGetUser(self): with reversion.create_revision(): reversion.set_user(self.user) self.assertEqual(reversion.get_user(), self.user) def testGetUserDefault(self): with reversion.create_revision(): self.assertEqual(reversion.get_user(), None) def testGetUserNoBlock(self): with self.assertRaises(reversion.RevisionManagementError): reversion.get_user() class SetDateCreatedTest(TestModelMixin, TestBase): def testSetDateCreated(self): date_created = timezone.now() - timedelta(days=20) with reversion.create_revision(): reversion.set_date_created(date_created) obj = TestModel.objects.create() self.assertSingleRevision((obj,), date_created=date_created) def testDateCreatedNoBlock(self): with self.assertRaises(reversion.RevisionManagementError): reversion.set_date_created(timezone.now()) class GetDateCreatedTest(TestBase): def testGetDateCreated(self): date_created = timezone.now() - timedelta(days=20) with reversion.create_revision(): reversion.set_date_created(date_created) self.assertEqual(reversion.get_date_created(), date_created) def testGetDateCreatedDefault(self): with reversion.create_revision(): self.assertAlmostEqual(reversion.get_date_created(), timezone.now(), delta=timedelta(seconds=1)) def testGetDateCreatedNoBlock(self): with self.assertRaises(reversion.RevisionManagementError): reversion.get_date_created() class AddMetaTest(TestModelMixin, TestBase): def testAddMeta(self): with reversion.create_revision(): reversion.add_meta(TestMeta, name="meta v1") obj = TestModel.objects.create() self.assertSingleRevision((obj,), meta_names=("meta v1",)) def testAddMetaNoBlock(self): with self.assertRaises(reversion.RevisionManagementError): reversion.add_meta(TestMeta, name="meta v1") def testAddMetaMultDb(self): with reversion.create_revision(using="mysql"), reversion.create_revision(using="postgres"): obj = TestModel.objects.create() reversion.add_meta(TestMeta, name="meta v1") self.assertNoRevision() self.assertSingleRevision((obj,), meta_names=("meta v1",), using="mysql") self.assertSingleRevision((obj,), meta_names=("meta v1",), using="postgres") django-reversion-2.0.13/tests/test_app/tests/test_commands.py000066400000000000000000000164411323160775000244200ustar00rootroot00000000000000from datetime import timedelta from django.core.management import CommandError from django.utils import timezone import reversion from test_app.models import TestModel from test_app.tests.base import TestBase, TestModelMixin class CreateInitialRevisionsTest(TestModelMixin, TestBase): def testCreateInitialRevisions(self): obj = TestModel.objects.create() self.callCommand("createinitialrevisions") self.assertSingleRevision((obj,), comment="Initial version.") def testCreateInitialRevisionsAlreadyCreated(self): obj = TestModel.objects.create() self.callCommand("createinitialrevisions") self.callCommand("createinitialrevisions") self.assertSingleRevision((obj,), comment="Initial version.") class CreateInitialRevisionsAppLabelTest(TestModelMixin, TestBase): def testCreateInitialRevisionsAppLabel(self): obj = TestModel.objects.create() self.callCommand("createinitialrevisions", "test_app") self.assertSingleRevision((obj,), comment="Initial version.") def testCreateInitialRevisionsAppLabelMissing(self): with self.assertRaises(CommandError): self.callCommand("createinitialrevisions", "boom") def testCreateInitialRevisionsModel(self): obj = TestModel.objects.create() self.callCommand("createinitialrevisions", "test_app.TestModel") self.assertSingleRevision((obj,), comment="Initial version.") def testCreateInitialRevisionsModelMissing(self): with self.assertRaises(CommandError): self.callCommand("createinitialrevisions", "test_app.boom") def testCreateInitialRevisionsModelMissingApp(self): with self.assertRaises(CommandError): self.callCommand("createinitialrevisions", "boom.boom") def testCreateInitialRevisionsModelNotRegistered(self): TestModel.objects.create() self.callCommand("createinitialrevisions", "auth.User") self.assertNoRevision() class CreateInitialRevisionsDbTest(TestModelMixin, TestBase): def testCreateInitialRevisionsDb(self): obj = TestModel.objects.create() self.callCommand("createinitialrevisions", using="postgres") self.assertNoRevision() self.assertSingleRevision((obj,), comment="Initial version.", using="postgres") def testCreateInitialRevisionsDbMySql(self): obj = TestModel.objects.create() self.callCommand("createinitialrevisions", using="mysql") self.assertNoRevision() self.assertSingleRevision((obj,), comment="Initial version.", using="mysql") class CreateInitialRevisionsModelDbTest(TestModelMixin, TestBase): def testCreateInitialRevisionsModelDb(self): obj = TestModel.objects.db_manager("postgres").create() self.callCommand("createinitialrevisions", model_db="postgres") self.assertSingleRevision((obj,), comment="Initial version.", model_db="postgres") class CreateInitialRevisionsCommentTest(TestModelMixin, TestBase): def testCreateInitialRevisionsComment(self): obj = TestModel.objects.create() self.callCommand("createinitialrevisions", comment="comment v1") self.assertSingleRevision((obj,), comment="comment v1") class DeleteRevisionsTest(TestModelMixin, TestBase): def testDeleteRevisions(self): with reversion.create_revision(): TestModel.objects.create() self.callCommand("deleterevisions") self.assertNoRevision() class DeleteRevisionsAppLabelTest(TestModelMixin, TestBase): def testDeleteRevisionsAppLabel(self): with reversion.create_revision(): TestModel.objects.create() self.callCommand("deleterevisions", "test_app") self.assertNoRevision() def testDeleteRevisionsAppLabelMissing(self): with self.assertRaises(CommandError): self.callCommand("deleterevisions", "boom") def testDeleteRevisionsModel(self): with reversion.create_revision(): TestModel.objects.create() self.callCommand("deleterevisions", "test_app.TestModel") self.assertNoRevision() def testDeleteRevisionsModelMissing(self): with self.assertRaises(CommandError): self.callCommand("deleterevisions", "test_app.boom") def testDeleteRevisionsModelMissingApp(self): with self.assertRaises(CommandError): self.callCommand("deleterevisions", "boom.boom") def testDeleteRevisionsModelNotRegistered(self): with reversion.create_revision(): obj = TestModel.objects.create() self.callCommand("deleterevisions", "auth.User") self.assertSingleRevision((obj,)) class DeleteRevisionsDbTest(TestModelMixin, TestBase): def testDeleteRevisionsDb(self): with reversion.create_revision(using="postgres"): TestModel.objects.create() self.callCommand("deleterevisions", using="postgres") self.assertNoRevision(using="postgres") def testDeleteRevisionsDbMySql(self): with reversion.create_revision(using="mysql"): TestModel.objects.create() self.callCommand("deleterevisions", using="mysql") self.assertNoRevision(using="mysql") def testDeleteRevisionsDbNoMatch(self): with reversion.create_revision(): obj = TestModel.objects.create() self.callCommand("deleterevisions", using="postgres") self.assertSingleRevision((obj,)) class DeleteRevisionsModelDbTest(TestModelMixin, TestBase): def testDeleteRevisionsModelDb(self): with reversion.create_revision(): TestModel.objects.db_manager("postgres").create() self.callCommand("deleterevisions", model_db="postgres") self.assertNoRevision(using="postgres") class DeleteRevisionsDaysTest(TestModelMixin, TestBase): def testDeleteRevisionsDays(self): date_created = timezone.now() - timedelta(days=20) with reversion.create_revision(): TestModel.objects.create() reversion.set_date_created(date_created) self.callCommand("deleterevisions", days=19) self.assertNoRevision() def testDeleteRevisionsDaysNoMatch(self): date_created = timezone.now() - timedelta(days=20) with reversion.create_revision(): obj = TestModel.objects.create() reversion.set_date_created(date_created) self.callCommand("deleterevisions", days=21) self.assertSingleRevision((obj,), date_created=date_created) class DeleteRevisionsKeepTest(TestModelMixin, TestBase): def testDeleteRevisionsKeep(self): with reversion.create_revision(): obj_1 = TestModel.objects.create() reversion.set_comment("obj_1 v1") with reversion.create_revision(): obj_1.save() reversion.set_comment("obj_1 v2") with reversion.create_revision(): obj_2 = TestModel.objects.create() reversion.set_comment("obj_2 v1") with reversion.create_revision(): obj_2.save() reversion.set_comment("obj_2 v2") with reversion.create_revision(): obj_3 = TestModel.objects.create() self.callCommand("deleterevisions", keep=1) self.assertSingleRevision((obj_1,), comment="obj_1 v2") self.assertSingleRevision((obj_2,), comment="obj_2 v2") self.assertSingleRevision((obj_3,)) django-reversion-2.0.13/tests/test_app/tests/test_middleware.py000066400000000000000000000023731323160775000247330ustar00rootroot00000000000000from django.conf import settings from django.test.utils import override_settings from test_app.models import TestModel from test_app.tests.base import TestBase, TestModelMixin, LoginMixin use_middleware = override_settings( MIDDLEWARE=settings.MIDDLEWARE + ["reversion.middleware.RevisionMiddleware"], MIDDLEWARE_CLASSES=settings.MIDDLEWARE_CLASSES + ["reversion.middleware.RevisionMiddleware"], ) @use_middleware class RevisionMiddlewareTest(TestModelMixin, TestBase): def testCreateRevision(self): response = self.client.post("/test-app/save-obj/") obj = TestModel.objects.get(pk=response.content) self.assertSingleRevision((obj,)) def testCreateRevisionError(self): with self.assertRaises(Exception): self.client.post("/test-app/save-obj-error/") self.assertNoRevision() def testCreateRevisionGet(self): self.client.get("/test-app/create-revision/") self.assertNoRevision() @use_middleware class RevisionMiddlewareUserTest(TestModelMixin, LoginMixin, TestBase): def testCreateRevisionUser(self): response = self.client.post("/test-app/save-obj/") obj = TestModel.objects.get(pk=response.content) self.assertSingleRevision((obj,), user=self.user) django-reversion-2.0.13/tests/test_app/tests/test_models.py000066400000000000000000000344641323160775000241070ustar00rootroot00000000000000from django.utils.encoding import force_text import reversion from reversion.models import Version from test_app.models import TestModel, TestModelRelated, TestModelParent from test_app.tests.base import TestBase, TestModelMixin, TestModelParentMixin class GetForModelTest(TestModelMixin, TestBase): def testGetForModel(self): with reversion.create_revision(): obj = TestModel.objects.create() self.assertEqual(Version.objects.get_for_model(obj.__class__).count(), 1) class GetForModelDbTest(TestModelMixin, TestBase): def testGetForModelDb(self): with reversion.create_revision(using="postgres"): obj = TestModel.objects.create() self.assertEqual(Version.objects.using("postgres").get_for_model(obj.__class__).count(), 1) def testGetForModelDbMySql(self): with reversion.create_revision(using="mysql"): obj = TestModel.objects.create() self.assertEqual(Version.objects.using("mysql").get_for_model(obj.__class__).count(), 1) class GetForObjectTest(TestModelMixin, TestBase): def testGetForObject(self): with reversion.create_revision(): obj = TestModel.objects.create() self.assertEqual(Version.objects.get_for_object(obj).count(), 1) def testGetForObjectEmpty(self): obj = TestModel.objects.create() self.assertEqual(Version.objects.get_for_object(obj).count(), 0) def testGetForObjectOrdering(self): with reversion.create_revision(): obj = TestModel.objects.create() with reversion.create_revision(): obj.name = "v2" obj.save() self.assertEqual(Version.objects.get_for_object(obj)[0].field_dict["name"], "v2") self.assertEqual(Version.objects.get_for_object(obj)[1].field_dict["name"], "v1") def testGetForObjectFiltering(self): with reversion.create_revision(): obj_1 = TestModel.objects.create() with reversion.create_revision(): obj_2 = TestModel.objects.create() self.assertEqual(Version.objects.get_for_object(obj_1).get().object, obj_1) self.assertEqual(Version.objects.get_for_object(obj_2).get().object, obj_2) class GetForObjectDbTest(TestModelMixin, TestBase): def testGetForObjectDb(self): with reversion.create_revision(using="postgres"): obj = TestModel.objects.create() self.assertEqual(Version.objects.get_for_object(obj).count(), 0) self.assertEqual(Version.objects.using("postgres").get_for_object(obj).count(), 1) def testGetForObjectDbMySql(self): with reversion.create_revision(using="mysql"): obj = TestModel.objects.create() self.assertEqual(Version.objects.get_for_object(obj).count(), 0) self.assertEqual(Version.objects.using("mysql").get_for_object(obj).count(), 1) class GetForObjectModelDbTest(TestModelMixin, TestBase): def testGetForObjectModelDb(self): with reversion.create_revision(): obj = TestModel.objects.db_manager("postgres").create() self.assertEqual(Version.objects.get_for_object(obj).count(), 0) self.assertEqual(Version.objects.get_for_object(obj, model_db="postgres").count(), 1) class GetForObjectUniqueTest(TestModelMixin, TestBase): def testGetForObjectUnique(self): with reversion.create_revision(): obj = TestModel.objects.create() with reversion.create_revision(): obj.save() self.assertEqual(len(list(Version.objects.get_for_object(obj).get_unique())), 1) def testGetForObjectUniqueMiss(self): with reversion.create_revision(): obj = TestModel.objects.create() with reversion.create_revision(): obj.name = "v2" obj.save() self.assertEqual(len(list(Version.objects.get_for_object(obj).get_unique())), 2) class GetForObjectReferenceTest(TestModelMixin, TestBase): def testGetForObjectReference(self): with reversion.create_revision(): obj = TestModel.objects.create() self.assertEqual(Version.objects.get_for_object_reference(TestModel, obj.pk).count(), 1) def testGetForObjectReferenceEmpty(self): obj = TestModel.objects.create() self.assertEqual(Version.objects.get_for_object_reference(TestModel, obj.pk).count(), 0) def testGetForObjectReferenceOrdering(self): with reversion.create_revision(): obj = TestModel.objects.create() with reversion.create_revision(): obj.name = "v2" obj.save() self.assertEqual(Version.objects.get_for_object_reference(TestModel, obj.pk)[0].field_dict["name"], "v2") self.assertEqual(Version.objects.get_for_object_reference(TestModel, obj.pk)[1].field_dict["name"], "v1") def testGetForObjectReferenceFiltering(self): with reversion.create_revision(): obj_1 = TestModel.objects.create() with reversion.create_revision(): obj_2 = TestModel.objects.create() self.assertEqual(Version.objects.get_for_object_reference(TestModel, obj_1.pk).get().object, obj_1) self.assertEqual(Version.objects.get_for_object_reference(TestModel, obj_2.pk).get().object, obj_2) class GetForObjectReferenceDbTest(TestModelMixin, TestBase): def testGetForObjectReferenceModelDb(self): with reversion.create_revision(using="postgres"): obj = TestModel.objects.create() self.assertEqual(Version.objects.get_for_object_reference(TestModel, obj.pk).count(), 0) self.assertEqual(Version.objects.using("postgres").get_for_object_reference(TestModel, obj.pk).count(), 1) class GetForObjectReferenceModelDbTest(TestModelMixin, TestBase): def testGetForObjectReferenceModelDb(self): with reversion.create_revision(): obj = TestModel.objects.db_manager("postgres").create() self.assertEqual(Version.objects.get_for_object_reference(TestModel, obj.pk).count(), 0) self.assertEqual(Version.objects.get_for_object_reference(TestModel, obj.pk, model_db="postgres").count(), 1) def testGetForObjectReferenceModelDbMySql(self): with reversion.create_revision(): obj = TestModel.objects.db_manager("mysql").create() self.assertEqual(Version.objects.get_for_object_reference(TestModel, obj.pk).count(), 0) self.assertEqual(Version.objects.get_for_object_reference(TestModel, obj.pk, model_db="mysql").count(), 1) class GetDeletedTest(TestModelMixin, TestBase): def testGetDeleted(self): with reversion.create_revision(): obj = TestModel.objects.create() with reversion.create_revision(): obj.save() obj.delete() self.assertEqual(Version.objects.get_deleted(TestModel).count(), 1) def testGetDeletedEmpty(self): with reversion.create_revision(): TestModel.objects.create() self.assertEqual(Version.objects.get_deleted(TestModel).count(), 0) def testGetDeletedOrdering(self): with reversion.create_revision(): obj_1 = TestModel.objects.create() with reversion.create_revision(): obj_2 = TestModel.objects.create() pk_1 = obj_1.pk obj_1.delete() pk_2 = obj_2.pk obj_2.delete() self.assertEqual(Version.objects.get_deleted(TestModel)[0].object_id, force_text(pk_2)) self.assertEqual(Version.objects.get_deleted(TestModel)[1].object_id, force_text(pk_1)) def testGetDeletedPostgres(self): with reversion.create_revision(using="postgres"): obj = TestModel.objects.using("postgres").create() with reversion.create_revision(using="postgres"): obj.save() obj.delete() self.assertEqual(Version.objects.using("postgres").get_deleted(TestModel, model_db="postgres").count(), 1) def testGetDeletedMySQL(self): with reversion.create_revision(using="mysql"): obj = TestModel.objects.using("mysql").create() with reversion.create_revision(using="mysql"): obj.save() obj.delete() self.assertEqual(Version.objects.using("mysql").get_deleted(TestModel, model_db="mysql").count(), 1) class GetDeletedDbTest(TestModelMixin, TestBase): def testGetDeletedDb(self): with reversion.create_revision(using="postgres"): obj = TestModel.objects.create() obj.delete() self.assertEqual(Version.objects.get_deleted(TestModel).count(), 0) self.assertEqual(Version.objects.using("postgres").get_deleted(TestModel).count(), 1) def testGetDeletedDbMySql(self): with reversion.create_revision(using="mysql"): obj = TestModel.objects.create() obj.delete() self.assertEqual(Version.objects.get_deleted(TestModel).count(), 0) self.assertEqual(Version.objects.using("mysql").get_deleted(TestModel).count(), 1) class GetDeletedModelDbTest(TestModelMixin, TestBase): def testGetDeletedModelDb(self): with reversion.create_revision(): obj = TestModel.objects.db_manager("postgres").create() obj.delete() self.assertEqual(Version.objects.get_deleted(TestModel).count(), 0) self.assertEqual(Version.objects.get_deleted(TestModel, model_db="postgres").count(), 1) class FieldDictTest(TestModelMixin, TestBase): def testFieldDict(self): with reversion.create_revision(): obj = TestModel.objects.create() self.assertEqual(Version.objects.get_for_object(obj).get().field_dict, { "id": obj.pk, "name": "v1", "related": [], }) def testFieldDictM2M(self): obj_related = TestModelRelated.objects.create() with reversion.create_revision(): obj = TestModel.objects.create() obj.related.add(obj_related) self.assertEqual(Version.objects.get_for_object(obj).get().field_dict, { "id": obj.pk, "name": "v1", "related": [obj_related.pk], }) class FieldDictFieldsTest(TestBase): def testFieldDictFieldFields(self): reversion.register(TestModel, fields=("name",)) with reversion.create_revision(): obj = TestModel.objects.create() self.assertEqual(Version.objects.get_for_object(obj).get().field_dict, { "name": "v1", }) class FieldDictExcludeTest(TestBase): def testFieldDictFieldExclude(self): reversion.register(TestModel, exclude=("name",)) with reversion.create_revision(): obj = TestModel.objects.create() self.assertEqual(Version.objects.get_for_object(obj).get().field_dict, { "id": obj.pk, "related": [], }) class FieldDictInheritanceTest(TestModelParentMixin, TestBase): def testFieldDictInheritance(self): with reversion.create_revision(): obj = TestModelParent.objects.create() self.assertEqual(Version.objects.get_for_object(obj).get().field_dict, { "id": obj.pk, "name": "v1", "related": [], "parent_name": "parent v1", "testmodel_ptr_id": obj.pk, }) def testFieldDictInheritanceUpdate(self): obj = TestModelParent.objects.create() with reversion.create_revision(): obj.name = "v2" obj.parent_name = "parent v2" obj.save() self.assertEqual(Version.objects.get_for_object(obj).get().field_dict, { "id": obj.pk, "name": "v2", "parent_name": "parent v2", "related": [], "testmodel_ptr_id": obj.pk, }) class M2MTest(TestModelMixin, TestBase): def testM2MSave(self): v1 = TestModelRelated.objects.create(name="v1") v2 = TestModelRelated.objects.create(name="v2") with reversion.create_revision(): obj = TestModel.objects.create() obj.related.add(v1) obj.related.add(v2) version = Version.objects.get_for_object(obj).first() self.assertEqual(set(version.field_dict["related"]), set((v1.pk, v2.pk,))) class RevertTest(TestModelMixin, TestBase): def testRevert(self): with reversion.create_revision(): obj = TestModel.objects.create() with reversion.create_revision(): obj.name = "v2" obj.save() Version.objects.get_for_object(obj)[1].revert() obj.refresh_from_db() self.assertEqual(obj.name, "v1") def testRevertBadSerializedData(self): with reversion.create_revision(): obj = TestModel.objects.create() Version.objects.get_for_object(obj).update(serialized_data="boom") with self.assertRaises(reversion.RevertError): Version.objects.get_for_object(obj).get().revert() def testRevertBadFormat(self): with reversion.create_revision(): obj = TestModel.objects.create() Version.objects.get_for_object(obj).update(format="boom") with self.assertRaises(reversion.RevertError): Version.objects.get_for_object(obj).get().revert() class RevisionRevertTest(TestModelMixin, TestBase): def testRevert(self): with reversion.create_revision(): obj_1 = TestModel.objects.create( name="obj_1 v1" ) obj_2 = TestModel.objects.create( name="obj_2 v1" ) with reversion.create_revision(): obj_1.name = "obj_1 v2" obj_1.save() obj_2.name = "obj_2 v2" obj_2.save() Version.objects.get_for_object(obj_1)[1].revision.revert() obj_1.refresh_from_db() self.assertEqual(obj_1.name, "obj_1 v1") obj_2.refresh_from_db() self.assertEqual(obj_2.name, "obj_2 v1") class RevisionRevertDeleteTest(TestBase): def testRevertDelete(self): reversion.register(TestModel, follow=("related",)) reversion.register(TestModelRelated) with reversion.create_revision(): obj = TestModel.objects.create() obj_related = TestModelRelated.objects.create() with reversion.create_revision(): obj.related.add(obj_related) obj.name = "v2" obj.save() Version.objects.get_for_object(obj)[1].revision.revert(delete=True) obj.refresh_from_db() self.assertEqual(obj.name, "v1") self.assertFalse(TestModelRelated.objects.filter(pk=obj_related.pk).exists()) django-reversion-2.0.13/tests/test_app/tests/test_views.py000066400000000000000000000026341323160775000237530ustar00rootroot00000000000000from test_app.models import TestModel from test_app.tests.base import TestBase, TestModelMixin, LoginMixin class CreateRevisionTest(TestModelMixin, TestBase): def testCreateRevision(self): response = self.client.post("/test-app/create-revision/") obj = TestModel.objects.get(pk=response.content) self.assertSingleRevision((obj,)) def testCreateRevisionGet(self): self.client.get("/test-app/create-revision/") self.assertNoRevision() class CreateRevisionUserTest(LoginMixin, TestModelMixin, TestBase): def testCreateRevisionUser(self): response = self.client.post("/test-app/create-revision/") obj = TestModel.objects.get(pk=response.content) self.assertSingleRevision((obj,), user=self.user) class RevisionMixinTest(TestModelMixin, TestBase): def testRevisionMixin(self): response = self.client.post("/test-app/revision-mixin/") obj = TestModel.objects.get(pk=response.content) self.assertSingleRevision((obj,)) def testRevisionMixinGet(self): self.client.get("/test-app/revision-mixin/") self.assertNoRevision() class RevisionMixinUserTest(LoginMixin, TestModelMixin, TestBase): def testCreateRevisionUser(self): response = self.client.post("/test-app/revision-mixin/") obj = TestModel.objects.get(pk=response.content) self.assertSingleRevision((obj,), user=self.user) django-reversion-2.0.13/tests/test_app/urls.py000066400000000000000000000004561323160775000214020ustar00rootroot00000000000000from django.conf.urls import url from test_app import views urlpatterns = [ url("^save-obj/", views.save_obj_view), url("^save-obj-error/", views.save_obj_error_view), url("^create-revision/", views.create_revision_view), url("^revision-mixin/", views.RevisionMixinView.as_view()), ] django-reversion-2.0.13/tests/test_app/views.py000066400000000000000000000010701323160775000215430ustar00rootroot00000000000000from django.http import HttpResponse from django.views.generic.base import View from reversion.views import create_revision, RevisionMixin from test_app.models import TestModel def save_obj_view(request): return HttpResponse(TestModel.objects.create().id) def save_obj_error_view(request): TestModel.objects.create() raise Exception("Boom!") @create_revision() def create_revision_view(request): return save_obj_view(request) class RevisionMixinView(RevisionMixin, View): def dispatch(self, request): return save_obj_view(request) django-reversion-2.0.13/tests/test_project/000077500000000000000000000000001323160775000207245ustar00rootroot00000000000000django-reversion-2.0.13/tests/test_project/__init__.py000066400000000000000000000000001323160775000230230ustar00rootroot00000000000000django-reversion-2.0.13/tests/test_project/settings.py000066400000000000000000000073351323160775000231460ustar00rootroot00000000000000""" Django settings for test_project project. Generated by "django-admin startproject" using Django 1.10a1. For more information on this file, see https://docs.djangoproject.com/en/dev/topics/settings/ For the full list of settings and their values, see https://docs.djangoproject.com/en/dev/ref/settings/ """ import os import getpass # Build paths inside the project like this: os.path.join(BASE_DIR, ...) BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) # Quick-start development settings - unsuitable for production # See https://docs.djangoproject.com/en/dev/howto/deployment/checklist/ # SECURITY WARNING: keep the secret key used in production secret! SECRET_KEY = "lzu78x^s$rit0p*vdt)$1e&hh*)4y=xv))=@zsx(am7t=7406a" # SECURITY WARNING: don"t run with debug turned on in production! DEBUG = True ALLOWED_HOSTS = [] # Application definition INSTALLED_APPS = [ "django.contrib.admin", "django.contrib.auth", "django.contrib.contenttypes", "django.contrib.sessions", "django.contrib.messages", "django.contrib.staticfiles", "reversion", "test_app", ] MIDDLEWARE = MIDDLEWARE_CLASSES = [ "django.middleware.security.SecurityMiddleware", "django.contrib.sessions.middleware.SessionMiddleware", "django.middleware.common.CommonMiddleware", "django.middleware.csrf.CsrfViewMiddleware", "django.contrib.auth.middleware.AuthenticationMiddleware", "django.contrib.messages.middleware.MessageMiddleware", "django.middleware.clickjacking.XFrameOptionsMiddleware", ] ROOT_URLCONF = "test_project.urls" TEMPLATES = [ { "BACKEND": "django.template.backends.django.DjangoTemplates", "DIRS": [], "APP_DIRS": True, "OPTIONS": { "context_processors": [ "django.template.context_processors.debug", "django.template.context_processors.request", "django.contrib.auth.context_processors.auth", "django.contrib.messages.context_processors.messages", ], }, }, ] WSGI_APPLICATION = "test_project.wsgi.application" # Database # https://docs.djangoproject.com/en/dev/ref/settings/#databases DATABASES = { "default": { "ENGINE": "django.db.backends.sqlite3", "NAME": os.path.join(BASE_DIR, "db.sqlite3"), }, "postgres": { "ENGINE": "django.db.backends.postgresql_psycopg2", "NAME": os.environ.get("DJANGO_DATABASE_NAME_POSTGRES", "test_project"), "USER": os.environ.get("DJANGO_DATABASE_USER_POSTGRES", getpass.getuser()), "PASSWORD": os.environ.get("DJANGO_DATABASE_PASSWORD_POSTGRES", ""), }, "mysql": { "ENGINE": "django.db.backends.mysql", "NAME": os.environ.get("DJANGO_DATABASE_NAME_MYSQL", "test_project"), "USER": os.environ.get("DJANGO_DATABASE_USER_MYSQL", getpass.getuser()), "PASSWORD": os.environ.get("DJANGO_DATABASE_PASSWORD_MYSQL", ""), }, } # Password validation # https://docs.djangoproject.com/en/dev/ref/settings/#auth-password-validators AUTH_PASSWORD_VALIDATORS = [ { "NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator", }, { "NAME": "django.contrib.auth.password_validation.MinimumLengthValidator", }, { "NAME": "django.contrib.auth.password_validation.CommonPasswordValidator", }, { "NAME": "django.contrib.auth.password_validation.NumericPasswordValidator", }, ] # Internationalization # https://docs.djangoproject.com/en/dev/topics/i18n/ LANGUAGE_CODE = "en-us" TIME_ZONE = "UTC" USE_I18N = True USE_L10N = True USE_TZ = True # Static files (CSS, JavaScript, Images) # https://docs.djangoproject.com/en/dev/howto/static-files/ STATIC_URL = "/static/" django-reversion-2.0.13/tests/test_project/urls.py000066400000000000000000000003171323160775000222640ustar00rootroot00000000000000from django.conf.urls import url, include from django.contrib import admin admin.autodiscover() urlpatterns = [ url(r"^admin/", admin.site.urls), url(r"^test-app/", include("test_app.urls")), ] django-reversion-2.0.13/tests/test_project/wsgi.py000066400000000000000000000006211323160775000222460ustar00rootroot00000000000000""" WSGI config for test_project project. It exposes the WSGI callable as a module-level variable named ``application``. For more information on this file, see https://docs.djangoproject.com/en/dev/howto/deployment/wsgi/ """ import os from django.core.wsgi import get_wsgi_application os.environ.setdefault("DJANGO_SETTINGS_MODULE", "test_project.settings") application = get_wsgi_application()