diff --git a/apps/trash/__init__.py b/apps/trash/__init__.py index 6a9fb6946f..8b13789179 100644 --- a/apps/trash/__init__.py +++ b/apps/trash/__init__.py @@ -1,32 +1 @@ -from __future__ import absolute_import -from django.utils.translation import ugettext_lazy as _ -from django.db import transaction, DatabaseError - -from documents.models import Document -from folders.models import Folder -from navigation.api import bind_links -from taggit.models import Tag - -from .api import make_trashable -from .links import trash_can_list, trash_can_items, trash_can_item_restore, trash_can_item_delete -from .models import TrashCan, TrashCanItem - -bind_links(['trash_can_list', TrashCan], trash_can_list, menu_name='secondary_menu') -bind_links([TrashCan], trash_can_items) -bind_links([TrashCanItem], [trash_can_item_restore, trash_can_item_delete]) - -@transaction.commit_on_success -def create_trash_cans(): - try: - documents_trash_can, created = TrashCan.objects.get_or_create(name='documents', defaults={'label': _(u'Documents')}) - folders_trash_can, created = TrashCan.objects.get_or_create(name='folders', defaults={'label': _(u'Folders')}) - tags_trash_can, created = TrashCan.objects.get_or_create(name='tags', defaults={'label': _(u'Tags')}) - except DatabaseError: - transaction.rollback() - else: - make_trashable(Document, documents_trash_can) - make_trashable(Folder, folders_trash_can) - make_trashable(Tag, tags_trash_can) - -create_trash_cans() diff --git a/apps/trash/migrations/0001_initial.py b/apps/trash/migrations/0001_initial.py new file mode 100644 index 0000000000..df5c2ef63e --- /dev/null +++ b/apps/trash/migrations/0001_initial.py @@ -0,0 +1,66 @@ +# -*- 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 'TrashCan' + db.create_table('trash_trashcan', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('name', self.gf('django.db.models.fields.CharField')(unique=True, max_length=32)), + )) + db.send_create_signal('trash', ['TrashCan']) + + # Adding model 'TrashCanItem' + db.create_table('trash_trashcanitem', ( + ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), + ('trash_can', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['trash.TrashCan'])), + ('trashed_at', self.gf('django.db.models.fields.DateTimeField')()), + ('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', ['TrashCanItem']) + + # Adding unique constraint on 'TrashCanItem', fields ['trash_can', 'content_type', 'object_id'] + db.create_unique('trash_trashcanitem', ['trash_can_id', 'content_type_id', 'object_id']) + + + def backwards(self, orm): + # Removing unique constraint on 'TrashCanItem', fields ['trash_can', 'content_type', 'object_id'] + db.delete_unique('trash_trashcanitem', ['trash_can_id', 'content_type_id', 'object_id']) + + # Deleting model 'TrashCan' + db.delete_table('trash_trashcan') + + # Deleting model 'TrashCanItem' + db.delete_table('trash_trashcanitem') + + + 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.trashcan': { + 'Meta': {'object_name': 'TrashCan'}, + 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), + 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '32'}) + }, + 'trash.trashcanitem': { + 'Meta': {'unique_together': "(('trash_can', 'content_type', 'object_id'),)", 'object_name': 'TrashCanItem'}, + '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', [], {}), + 'trash_can': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['trash.TrashCan']"}), + 'trashed_at': ('django.db.models.fields.DateTimeField', [], {}) + } + } + + complete_apps = ['trash'] \ No newline at end of file diff --git a/apps/trash/models.py b/apps/trash/models.py index 18acba0078..57334dcba9 100644 --- a/apps/trash/models.py +++ b/apps/trash/models.py @@ -4,19 +4,36 @@ 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 _ +from django.db import transaction, DatabaseError from common.managers import CustomizableQuerySetManager +from common.querysets import CustomizableQuerySet +from common.models import TranslatableLabelMixin class TrashCanManager(models.Manager): - def get_or_create(self, *args, **kwargs): - instance, created = super(TrashCanManager, self).get_or_create(*args, **kwargs) - instance.label = kwargs.get('defaults', {}).get('label') - instance.save() - return instance, created + @transaction.commit_on_success + def make_trashable(self, full_model_name, label=None): + app_name, model_name = full_model_name.split('.') + model = models.get_model(app_name, model_name) + if model: + try: + trash_can, created = self.model.objects.get_or_create(name=app_name) + except DatabaseError: + transaction.rollback() + else: + trash_can.label = label or model._meta.verbose_name_plural + old_manager = getattr(model, '_default_manager') + model.add_to_class('objects', CustomizableQuerySet.as_manager(TrashableQuerySetManager)) + model._default_manager = model.objects + model.add_to_class('trash_passthru', old_manager) + + old_delete_method = model.delete + model.delete = new_delete_method(trash_can, old_delete_method) + - -class TrashCan(models.Model): +class TrashCan(TranslatableLabelMixin, models.Model): + translatables = ['label'] trash_can_labels = {} name = models.CharField(max_length=32, verbose_name=_(u'name'), unique=True) @@ -24,15 +41,7 @@ class TrashCan(models.Model): objects = TrashCanManager() def __unicode__(self): - return unicode(self.label) or self.names - - def _get_label(self): - return TrashCan.trash_can_labels.get(self.name) - - def _set_label(self, value): - TrashCan.trash_can_labels[self.name] = value - - label = property(_get_label, _set_label) + return unicode(self.label) or self.name def put(self, obj): # TODO: check if obj is trashable model diff --git a/apps/trash/post_init.py b/apps/trash/post_init.py new file mode 100644 index 0000000000..36952dfda3 --- /dev/null +++ b/apps/trash/post_init.py @@ -0,0 +1,19 @@ +from __future__ import absolute_import + +from django.utils.translation import ugettext_lazy as _ + +from navigation.api import bind_links + +from .links import trash_can_list, trash_can_items, trash_can_item_restore, trash_can_item_delete +from .models import TrashCan, TrashCanItem + + +def init_create_trash_cans(): + model_set = [('documents.Document', _(u'Documents')), ('folders.Folder', _(u'Folders')), ('taggit.Tag', _(u'Tags'))] + for model_info in model_set: + TrashCan.objects.make_trashable(*model_info) + + +bind_links(['trash_can_list', TrashCan], trash_can_list, menu_name='secondary_menu') +bind_links([TrashCan], trash_can_items) +bind_links([TrashCanItem], [trash_can_item_restore, trash_can_item_delete])