Skip to content

Commit 274aba3

Browse files
committed
Fixed #11108 -- added ModelAdmin.delete_model, a hook with which to perform 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
1 parent 0cf1c96 commit 274aba3

File tree

5 files changed

+49
-4
lines changed

5 files changed

+49
-4
lines changed

django/contrib/admin/options.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,12 @@ def save_model(self, request, obj, form, change):
601601
"""
602602
obj.save()
603603

604+
def delete_model(self, requet, obj):
605+
"""
606+
Given a model instance delete it from the database.
607+
"""
608+
obj.delete()
609+
604610
def save_formset(self, request, form, formset, change):
605611
"""
606612
Given an inline formset save it to the database.
@@ -1122,7 +1128,7 @@ def delete_view(self, request, object_id, extra_context=None):
11221128
raise PermissionDenied
11231129
obj_display = force_unicode(obj)
11241130
self.log_deletion(request, obj, obj_display)
1125-
obj.delete()
1131+
self.delete_model(request, obj)
11261132

11271133
self.message_user(request, _('The %(name)s "%(obj)s" was deleted successfully.') % {'name': force_unicode(opts.verbose_name), 'obj': force_unicode(obj_display)})
11281134

docs/ref/contrib/admin/index.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,12 @@ templates used by the :class:`ModelAdmin` views:
757757
``ModelAdmin`` methods
758758
----------------------
759759

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+
760766
.. method:: ModelAdmin.save_model(self, request, obj, form, change)
761767

762768
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::
770776
obj.user = request.user
771777
obj.save()
772778

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+
773786
.. method:: ModelAdmin.save_formset(self, request, form, formset, change)
774787

775788
The ``save_formset`` method is given the ``HttpRequest``, the parent

docs/topics/db/multi-db.txt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ database other than that that specified by your router chain, you'll
458458
need to write custom :class:`~django.contrib.admin.ModelAdmin` classes
459459
that will direct the admin to use a specific database for content.
460460

461-
``ModelAdmin`` objects have four methods that require customization for
461+
``ModelAdmin`` objects have five methods that require customization for
462462
multiple-database support::
463463

464464
class MultiDBModelAdmin(admin.ModelAdmin):
@@ -469,6 +469,10 @@ multiple-database support::
469469
# Tell Django to save objects to the 'other' database.
470470
obj.save(using=self.using)
471471

472+
def delete_model(self, requqest, obj):
473+
# Tell Django to delete objects from the 'other' database
474+
obj.delete(using=self.using)
475+
472476
def queryset(self, request):
473477
# Tell Django to look for objects on the 'other' database.
474478
return super(MultiDBModelAdmin, self).queryset(request).using(self.using)

tests/regressiontests/admin_views/models.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,25 @@ def modeladmin_year(self, obj):
107107
modeladmin_year.admin_order_field = 'date'
108108
modeladmin_year.short_description = None
109109

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+
115+
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+
124+
125+
).send()
126+
return super(ArticleAdmin, self).save_model(request, obj, form, change)
127+
128+
110129
class CustomArticle(models.Model):
111130
content = models.TextField()
112131
date = models.DateTimeField()

tests/regressiontests/admin_views/tests.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import re
44
import datetime
55
from django.conf import settings
6+
from django.core import mail
67
from django.core.files import temp as tempfile
78
from django.contrib.auth import admin # Register auth models with the admin.
89
from django.contrib.auth.models import User, Permission, UNUSABLE_PASSWORD
@@ -540,6 +541,8 @@ def testAddView(self):
540541
post = self.client.post('/test_admin/admin/admin_views/article/add/', add_dict)
541542
self.assertRedirects(post, '/test_admin/admin/')
542543
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')
543546
self.client.get('/test_admin/admin/logout/')
544547

545548
# Super can add too, but is redirected to the change list view
@@ -695,6 +698,8 @@ def testDeleteView(self):
695698
post = self.client.post('/test_admin/admin/admin_views/article/1/delete/', delete_dict)
696699
self.assertRedirects(post, '/test_admin/admin/')
697700
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')
698703
article_ct = ContentType.objects.get_for_model(Article)
699704
logged = LogEntry.objects.get(content_type=article_ct, action_flag=DELETION)
700705
self.failUnlessEqual(logged.object_id, u'1')
@@ -1440,8 +1445,6 @@ def testInline(self):
14401445
self.failUnlessEqual(BarAccount.objects.all()[0].username, "%s-1" % bar_user)
14411446
self.failUnlessEqual(Persona.objects.all()[0].accounts.count(), 2)
14421447

1443-
from django.core import mail
1444-
14451448
class AdminActionsTest(TestCase):
14461449
fixtures = ['admin-views-users.xml', 'admin-views-actions.xml']
14471450

0 commit comments

Comments
 (0)