Allows model instances (and all related objects) to be un-deleted.
Python
Switch branches/tags
Nothing to show
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
resurrectable
.gitignore
README

README

django-resurrectable

Summary
-------

This is a basic implementation of "pseudo-deleting" model instances, so they can
be un-deleted later.

Terminology
-----------

This document uses the terms "undeleted" and "non-deleted" interchangeably,
since an object that has been deleted and then undeleted is indistinguishable
from one that has never been deleted at all.

Installation
------------

1) Put resurrectable/ somewhere in your PYTHONPATH.

2) Add resurrectable to the INSTALLED_APPS list in your settings.py file.

3) Subclass resurrectable.models.Resurrectable for any model that you want to be
   resurrectable.

4) (optional) Define a method called get_resurrectable_children() on your
   resurrectable model classes. This method should return an iterable of
   strings mapping to related objects that will be (un)deleted with this object.
   (See note below about the current abilities of cascading deletes).

   Example:

       from django.db import models
       from resurrectable.models import Resurrectable

       class Choice(models.Model):
           answer = models.CharField(max_length=80)
           poll = models.ForeignKey(Poll, related_name='choices')

       class Poll(Resurrectable, models.Model):
           question = models.CharField(max_length=80)

           def get_resurrectable_children(self):
               return ['choices']

5) Somehow add the 'deleted' date_time field to tables in your database that
   represent resurrectable models (e.g. drop the model tables and run
   manage.py syncdb, use a schema migration tool, sling some SQL, etc.).

(Un)deleting Objects
--------------------

* Deleting: To pseudo-delete an object, just call its delete() method as usual.
* Undeleting: Call the object's undelete() method.

Both methods support a 'cascade' keyword argument that defaults to True.
Calling either method with cascade=False will skip the (un)deleting of
objects specified by the object's resurrectable_children Meta attribute.

Querying for (Un)deleted Objects
--------------------------------

To get all objects (deleted and undeleted), simply query as you normally would:
    Foo.objects.all()
To get only objects that are deleted, call the deleted() method on a queryset:
    Foo.objects.all().deleted()
To get only objects that have not been deleted, call the not_deleted() method:
    Foo.objects.all().not_deleted()

A shortcut function (resurrectable.shortcuts.get_nondeleted_or_404()) exists
for easily getting a particular object while ensuring that it hasn't been
deleted. This function takes the same arguments as and behaves the same as
django.shortcuts.get_object_or_404, except if the object is deleted, Http404
is raised.

You can determine if an object has been deleted by calling object.is_deleted().

Admin
-----

ModelAdmin subclasses may also subclass resurrectable.admin.ResurrectableAdmin
to inherit two boolean methods:

 * is_deleted(self, object)
 * not_deleted(self, object)

These may be used anywhere a ModelAdmin method is allowed (e.g. list_display).

Notes
-----

* If you want to use a custom manager for any model subclassing Resurrectable,
  it should subclass ResurrectableManager (otherwise the queryset methods
  discussed above will not be available filtered out).

* Admin strings are currently English only.

* Cascading doesn't work yet.