From df527b1fd40414c056980dace4a3efbcfae9a781 Mon Sep 17 00:00:00 2001 From: Roberto Rosario Date: Mon, 6 Aug 2012 19:44:01 -0400 Subject: [PATCH] Initial commit of the trash app --- apps/trash/__init__.py | 7 ++++ apps/trash/admin.py | 13 +++++++ apps/trash/api.py | 15 ++++++++ apps/trash/migrations/0001_initial.py | 41 +++++++++++++++++++++ apps/trash/migrations/__init__.py | 0 apps/trash/models.py | 52 +++++++++++++++++++++++++++ apps/trash/urls.py | 4 +++ apps/trash/views.py | 1 + settings.py | 1 + urls.py | 1 + 10 files changed, 135 insertions(+) create mode 100644 apps/trash/__init__.py create mode 100644 apps/trash/admin.py create mode 100644 apps/trash/api.py create mode 100644 apps/trash/migrations/0001_initial.py create mode 100644 apps/trash/migrations/__init__.py create mode 100644 apps/trash/models.py create mode 100644 apps/trash/urls.py create mode 100644 apps/trash/views.py diff --git a/apps/trash/__init__.py b/apps/trash/__init__.py new file mode 100644 index 0000000000..6493b140cc --- /dev/null +++ b/apps/trash/__init__.py @@ -0,0 +1,7 @@ +from __future__ import absolute_import + +from documents.models import Document + +from .api import make_trashable + +make_trashable(Document) diff --git a/apps/trash/admin.py b/apps/trash/admin.py new file mode 100644 index 0000000000..03f25b7440 --- /dev/null +++ b/apps/trash/admin.py @@ -0,0 +1,13 @@ +from __future__ import absolute_import + +from django.contrib import admin + +from .models import TrashedItem + + +class TrashedItemAdmin(admin.ModelAdmin): + list_display = ('content_type', 'object_id', 'content_object',) + list_display_links = ('content_object',) + + +admin.site.register(TrashedItem, TrashedItemAdmin) diff --git a/apps/trash/api.py b/apps/trash/api.py new file mode 100644 index 0000000000..bbba8a8ae0 --- /dev/null +++ b/apps/trash/api.py @@ -0,0 +1,15 @@ +from __future__ import absolute_import + +from .models import TrashableModelManager, new_delete_method + + +trashable_models = [] +def make_trashable(model): + trashable_models.append(model) + #model.__class__.objects = TrashableModelManager() + #model.__class__._default_manager = TrashableModelManager() + #model.objects = TrashableModelManager() + model.add_to_class('objects', TrashableModelManager()) + old_delete_method = model.delete + model.delete = new_delete_method(old_delete_method) + #model.add_to_class('is_in_trash', return True) diff --git a/apps/trash/migrations/0001_initial.py b/apps/trash/migrations/0001_initial.py new file mode 100644 index 0000000000..683362218d --- /dev/null +++ b/apps/trash/migrations/0001_initial.py @@ -0,0 +1,41 @@ +# -*- coding: utf-8 -*- +import datetime +from south.db import db +from south.v2 import SchemaMigration +from django.db import models + + +class Migration(SchemaMigration): + + def forwards(self, orm): + # Adding model 'TrashedItem' + db.create_table('trash_trasheditem', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('content_type', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['contenttypes.ContentType'])), + ('object_id', self.gf('django.db.models.fields.PositiveIntegerField')()), + )) + db.send_create_signal('trash', ['TrashedItem']) + + + def backwards(self, orm): + # Deleting model 'TrashedItem' + db.delete_table('trash_trasheditem') + + + models = { + 'contenttypes.contenttype': { + 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"}, + 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}), + 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'}) + }, + 'trash.trasheditem': { + 'Meta': {'object_name': 'TrashedItem'}, + 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}), + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}) + } + } + + complete_apps = ['trash'] \ No newline at end of file diff --git a/apps/trash/migrations/__init__.py b/apps/trash/migrations/__init__.py new file mode 100644 index 0000000000..e69de29bb2 diff --git a/apps/trash/models.py b/apps/trash/models.py new file mode 100644 index 0000000000..21581c896e --- /dev/null +++ b/apps/trash/models.py @@ -0,0 +1,52 @@ +from django.contrib.contenttypes.models import ContentType +from django.contrib.contenttypes import generic +from django.db import models +from django.utils.translation import ugettext_lazy as _ + + +class TrashedItemManager(models.Manager): + def is_in_trash(self, obj): + content_type = ContentType.objects.get_for_model(obj) + try: + self.model.objects.get(content_type=content_type, object_id=obj.id) + except self.model.DoesNotExist: + return False + else: + return True + + def ids(self): + return [trash_item.object_id for trash_item in self.model.objects.all()] + + +class TrashedItem(models.Model): + #trashed_at = models.DateTimeField(_('Trashed at'), editable=False, blank=True, null=True) + content_type = models.ForeignKey(ContentType) + object_id = models.PositiveIntegerField() + content_object = generic.GenericForeignKey('content_type', 'object_id') + + objects = TrashedItemManager() + + def __unicode__(self): + return unicode(self.content_object) + + def restore(self): + self.delete() + + +def new_delete_method(old_delete_method): + def delete(self, *args, **kwargs): + trash = kwargs.pop('trash', True) + + if trash==False: + return old_delete_method(self, *args, **kwargs) + else: + trashed_item = TrashedItem.objects.create(content_object=self)#, trashed_at=datetime.now()) + + return delete + + +class TrashableModelManager(models.Manager): + def get_query_set(self): + print 'excluded', TrashedItem.objects.items() + query_set = super(TrashableModelManager, self).get_query_set().exclude(pk__in=TrashedItem.objects.ids()) + return query_set diff --git a/apps/trash/urls.py b/apps/trash/urls.py new file mode 100644 index 0000000000..daeab811ad --- /dev/null +++ b/apps/trash/urls.py @@ -0,0 +1,4 @@ +from django.conf.urls.defaults import patterns, url + +urlpatterns = patterns('trash.views', +) diff --git a/apps/trash/views.py b/apps/trash/views.py new file mode 100644 index 0000000000..60f00ef0ef --- /dev/null +++ b/apps/trash/views.py @@ -0,0 +1 @@ +# Create your views here. diff --git a/settings.py b/settings.py index aa54ec6371..fdd5d2ea68 100644 --- a/settings.py +++ b/settings.py @@ -190,6 +190,7 @@ INSTALLED_APPS = ( 'rest_api', 'bootstrap', 'statistics', + 'trash', # Has to be last so the other apps can register it's signals 'signaler', diff --git a/urls.py b/urls.py index 82b10cc5d1..665c8ad2de 100644 --- a/urls.py +++ b/urls.py @@ -42,6 +42,7 @@ urlpatterns = patterns('', (r'^maintenance/', include('maintenance.urls')), (r'^statistics/', include('statistics.urls')), (r'^clustering/', include('clustering.urls')), + (r'^trash/', include('trash.urls')), )