Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #11108 -- added ModelAdmin.delete_model, a hook with which to p…

…erform custom pre-post delete behavior. Thanks to Florian Apolloner for the patch.

git-svn-id: http://code.djangoproject.com/svn/django/trunk@14673 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit 274aba3b9b8c48012a2d842790cb3df04dc9ae80 1 parent 0cf1c96
Alex Gaynor authored November 21, 2010
8  django/contrib/admin/options.py
@@ -601,6 +601,12 @@ def save_model(self, request, obj, form, change):
601 601
         """
602 602
         obj.save()
603 603
 
  604
+    def delete_model(self, requet, obj):
  605
+        """
  606
+        Given a model instance delete it from the database.
  607
+        """
  608
+        obj.delete()
  609
+
604 610
     def save_formset(self, request, form, formset, change):
605 611
         """
606 612
         Given an inline formset save it to the database.
@@ -1122,7 +1128,7 @@ def delete_view(self, request, object_id, extra_context=None):
1122 1128
                 raise PermissionDenied
1123 1129
             obj_display = force_unicode(obj)
1124 1130
             self.log_deletion(request, obj, obj_display)
1125  
-            obj.delete()
  1131
+            self.delete_model(request, obj)
1126 1132
 
1127 1133
             self.message_user(request, _('The %(name)s "%(obj)s" was deleted successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(obj_display)})
1128 1134
 
13  docs/ref/contrib/admin/index.txt
@@ -757,6 +757,12 @@ templates used by the :class:`ModelAdmin` views:
757 757
 ``ModelAdmin`` methods
758 758
 ----------------------
759 759
 
  760
+.. warning::
  761
+
  762
+    :meth:`ModelAdmin.save_model` and :meth:`ModelAdmin.delete_model` must
  763
+    save/delete the object, they are not for veto purposes, rather they allow
  764
+    you to perform extra operations.
  765
+
760 766
 .. method:: ModelAdmin.save_model(self, request, obj, form, change)
761 767
 
762 768
 The ``save_model`` method is given the ``HttpRequest``, a model instance,
@@ -770,6 +776,13 @@ For example to attach ``request.user`` to the object prior to saving::
770 776
             obj.user = request.user
771 777
             obj.save()
772 778
 
  779
+.. method:: ModelAdmin.delete_model(self, request, obj)
  780
+
  781
+.. versionadded:: 1.3
  782
+
  783
+The ``delete_model`` method is given the ``HttpRequest`` and a model instance.
  784
+Use this method to do pre- or post-delete operations.
  785
+
773 786
 .. method:: ModelAdmin.save_formset(self, request, form, formset, change)
774 787
 
775 788
 The ``save_formset`` method is given the ``HttpRequest``, the parent
6  docs/topics/db/multi-db.txt
@@ -458,7 +458,7 @@ database other than that that specified by your router chain, you'll
458 458
 need to write custom :class:`~django.contrib.admin.ModelAdmin` classes
459 459
 that will direct the admin to use a specific database for content.
460 460
 
461  
-``ModelAdmin`` objects have four methods that require customization for
  461
+``ModelAdmin`` objects have five methods that require customization for
462 462
 multiple-database support::
463 463
 
464 464
     class MultiDBModelAdmin(admin.ModelAdmin):
@@ -469,6 +469,10 @@ multiple-database support::
469 469
             # Tell Django to save objects to the 'other' database.
470 470
             obj.save(using=self.using)
471 471
 
  472
+        def delete_model(self, requqest, obj):
  473
+            # Tell Django to delete objects from the 'other' database
  474
+            obj.delete(using=self.using)
  475
+
472 476
         def queryset(self, request):
473 477
             # Tell Django to look for objects on the 'other' database.
474 478
             return super(MultiDBModelAdmin, self).queryset(request).using(self.using)
19  tests/regressiontests/admin_views/models.py
@@ -107,6 +107,25 @@ def modeladmin_year(self, obj):
107 107
     modeladmin_year.admin_order_field = 'date'
108 108
     modeladmin_year.short_description = None
109 109
 
  110
+    def delete_model(self, request, obj):
  111
+        EmailMessage(
  112
+            'Greetings from a deleted object',
  113
+            'I hereby inform you that some user deleted me',
  114
+            'from@example.com',
  115
+            ['to@example.com']
  116
+        ).send()
  117
+        return super(ArticleAdmin, self).delete_model(request, obj)
  118
+
  119
+    def save_model(self, request, obj, form, change=True):
  120
+        EmailMessage(
  121
+            'Greetings from a created object',
  122
+            'I hereby inform you that some user created me',
  123
+            'from@example.com',
  124
+            ['to@example.com']
  125
+        ).send()
  126
+        return super(ArticleAdmin, self).save_model(request, obj, form, change)
  127
+
  128
+
110 129
 class CustomArticle(models.Model):
111 130
     content = models.TextField()
112 131
     date = models.DateTimeField()
7  tests/regressiontests/admin_views/tests.py
@@ -3,6 +3,7 @@
3 3
 import re
4 4
 import datetime
5 5
 from django.conf import settings
  6
+from django.core import mail
6 7
 from django.core.files import temp as tempfile
7 8
 from django.contrib.auth import admin # Register auth models with the admin.
8 9
 from django.contrib.auth.models import User, Permission, UNUSABLE_PASSWORD
@@ -540,6 +541,8 @@ def testAddView(self):
540 541
         post = self.client.post('/test_admin/admin/admin_views/article/add/', add_dict)
541 542
         self.assertRedirects(post, '/test_admin/admin/')
542 543
         self.failUnlessEqual(Article.objects.all().count(), 4)
  544
+        self.assertEquals(len(mail.outbox), 1)
  545
+        self.assertEquals(mail.outbox[0].subject, 'Greetings from a created object')
543 546
         self.client.get('/test_admin/admin/logout/')
544 547
 
545 548
         # Super can add too, but is redirected to the change list view
@@ -695,6 +698,8 @@ def testDeleteView(self):
695 698
         post = self.client.post('/test_admin/admin/admin_views/article/1/delete/', delete_dict)
696 699
         self.assertRedirects(post, '/test_admin/admin/')
697 700
         self.failUnlessEqual(Article.objects.all().count(), 2)
  701
+        self.assertEquals(len(mail.outbox), 1)
  702
+        self.assertEquals(mail.outbox[0].subject, 'Greetings from a deleted object')
698 703
         article_ct = ContentType.objects.get_for_model(Article)
699 704
         logged = LogEntry.objects.get(content_type=article_ct, action_flag=DELETION)
700 705
         self.failUnlessEqual(logged.object_id, u'1')
@@ -1440,8 +1445,6 @@ def testInline(self):
1440 1445
         self.failUnlessEqual(BarAccount.objects.all()[0].username, "%s-1" % bar_user)
1441 1446
         self.failUnlessEqual(Persona.objects.all()[0].accounts.count(), 2)
1442 1447
 
1443  
-from django.core import mail
1444  
-
1445 1448
 class AdminActionsTest(TestCase):
1446 1449
     fixtures = ['admin-views-users.xml', 'admin-views-actions.xml']
1447 1450
 

0 notes on commit 274aba3

Please sign in to comment.
Something went wrong with that request. Please try again.