diff --git a/django/contrib/admin/options.py b/django/contrib/admin/options.py
index ffc6e79..caaf09d 100644
a
|
b
|
class ModelAdmin(BaseModelAdmin):
|
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. |
… |
… |
class ModelAdmin(BaseModelAdmin):
|
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 | |
diff --git a/docs/ref/contrib/admin/index.txt b/docs/ref/contrib/admin/index.txt
index ac517e8..df41ab2 100644
a
|
b
|
templates used by the :class:`ModelAdmin` views:
|
757 | 757 | ``ModelAdmin`` methods |
758 | 758 | ---------------------- |
759 | 759 | |
| 760 | .. warning:: |
| 761 | |
| 762 | ``save_model`` and ``delete_model`` have to save/delete the object, those |
| 763 | methods are not for veto purposes, they just allow you to do some extra |
| 764 | 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, |
… |
… |
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 | The ``delete_model`` method is given the ``HttpRequest`` and a model instance. |
| 782 | Use this method to to pre- or post-delete operations. |
| 783 | |
773 | 784 | .. method:: ModelAdmin.save_formset(self, request, form, formset, change) |
774 | 785 | |
775 | 786 | The ``save_formset`` method is given the ``HttpRequest``, the parent |
diff --git a/docs/topics/db/multi-db.txt b/docs/topics/db/multi-db.txt
index 1a939b0..0e9290c 100644
a
|
b
|
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): |
… |
… |
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) |
diff --git a/tests/regressiontests/admin_views/models.py b/tests/regressiontests/admin_views/models.py
index b25a9b9..ee0f5d5 100644
a
|
b
|
class ArticleAdmin(admin.ModelAdmin):
|
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() |
diff --git a/tests/regressiontests/admin_views/tests.py b/tests/regressiontests/admin_views/tests.py
index 4c96306..a3fe34f 100644
a
|
b
|
|
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 |
… |
… |
class AdminViewPermissionsTest(TestCase):
|
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 |
… |
… |
class AdminViewPermissionsTest(TestCase):
|
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') |
… |
… |
class AdminInheritedInlinesTest(TestCase):
|
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 | |