Skip to content

Commit

Permalink
Fixed #11108 -- added ModelAdmin.delete_model, a hook with which to p…
Browse files Browse the repository at this point in the history
…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
alex committed Nov 21, 2010
1 parent 0cf1c96 commit 274aba3
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 4 deletions.
8 changes: 7 additions & 1 deletion django/contrib/admin/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,12 @@ def save_model(self, request, obj, form, change):
"""
obj.save()

def delete_model(self, requet, obj):
"""
Given a model instance delete it from the database.
"""
obj.delete()

def save_formset(self, request, form, formset, change):
"""
Given an inline formset save it to the database.
Expand Down Expand Up @@ -1122,7 +1128,7 @@ def delete_view(self, request, object_id, extra_context=None):
raise PermissionDenied
obj_display = force_unicode(obj)
self.log_deletion(request, obj, obj_display)
obj.delete()
self.delete_model(request, obj)

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

Expand Down
13 changes: 13 additions & 0 deletions docs/ref/contrib/admin/index.txt
Original file line number Diff line number Diff line change
Expand Up @@ -757,6 +757,12 @@ templates used by the :class:`ModelAdmin` views:
``ModelAdmin`` methods
----------------------

.. warning::

:meth:`ModelAdmin.save_model` and :meth:`ModelAdmin.delete_model` must
save/delete the object, they are not for veto purposes, rather they allow
you to perform extra operations.

.. method:: ModelAdmin.save_model(self, request, obj, form, change)

The ``save_model`` method is given the ``HttpRequest``, a model instance,
Expand All @@ -770,6 +776,13 @@ For example to attach ``request.user`` to the object prior to saving::
obj.user = request.user
obj.save()

.. method:: ModelAdmin.delete_model(self, request, obj)

.. versionadded:: 1.3

The ``delete_model`` method is given the ``HttpRequest`` and a model instance.
Use this method to do pre- or post-delete operations.

.. method:: ModelAdmin.save_formset(self, request, form, formset, change)

The ``save_formset`` method is given the ``HttpRequest``, the parent
Expand Down
6 changes: 5 additions & 1 deletion docs/topics/db/multi-db.txt
Original file line number Diff line number Diff line change
Expand Up @@ -458,7 +458,7 @@ database other than that that specified by your router chain, you'll
need to write custom :class:`~django.contrib.admin.ModelAdmin` classes
that will direct the admin to use a specific database for content.

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

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

def delete_model(self, requqest, obj):
# Tell Django to delete objects from the 'other' database
obj.delete(using=self.using)

def queryset(self, request):
# Tell Django to look for objects on the 'other' database.
return super(MultiDBModelAdmin, self).queryset(request).using(self.using)
Expand Down
19 changes: 19 additions & 0 deletions tests/regressiontests/admin_views/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,25 @@ def modeladmin_year(self, obj):
modeladmin_year.admin_order_field = 'date'
modeladmin_year.short_description = None

def delete_model(self, request, obj):
EmailMessage(
'Greetings from a deleted object',
'I hereby inform you that some user deleted me',
'from@example.com',
['to@example.com']
).send()
return super(ArticleAdmin, self).delete_model(request, obj)

def save_model(self, request, obj, form, change=True):
EmailMessage(
'Greetings from a created object',
'I hereby inform you that some user created me',
'from@example.com',
['to@example.com']
).send()
return super(ArticleAdmin, self).save_model(request, obj, form, change)


class CustomArticle(models.Model):
content = models.TextField()
date = models.DateTimeField()
Expand Down
7 changes: 5 additions & 2 deletions tests/regressiontests/admin_views/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import re
import datetime
from django.conf import settings
from django.core import mail
from django.core.files import temp as tempfile
from django.contrib.auth import admin # Register auth models with the admin.
from django.contrib.auth.models import User, Permission, UNUSABLE_PASSWORD
Expand Down Expand Up @@ -540,6 +541,8 @@ def testAddView(self):
post = self.client.post('/test_admin/admin/admin_views/article/add/', add_dict)
self.assertRedirects(post, '/test_admin/admin/')
self.failUnlessEqual(Article.objects.all().count(), 4)
self.assertEquals(len(mail.outbox), 1)
self.assertEquals(mail.outbox[0].subject, 'Greetings from a created object')
self.client.get('/test_admin/admin/logout/')

# Super can add too, but is redirected to the change list view
Expand Down Expand Up @@ -695,6 +698,8 @@ def testDeleteView(self):
post = self.client.post('/test_admin/admin/admin_views/article/1/delete/', delete_dict)
self.assertRedirects(post, '/test_admin/admin/')
self.failUnlessEqual(Article.objects.all().count(), 2)
self.assertEquals(len(mail.outbox), 1)
self.assertEquals(mail.outbox[0].subject, 'Greetings from a deleted object')
article_ct = ContentType.objects.get_for_model(Article)
logged = LogEntry.objects.get(content_type=article_ct, action_flag=DELETION)
self.failUnlessEqual(logged.object_id, u'1')
Expand Down Expand Up @@ -1440,8 +1445,6 @@ def testInline(self):
self.failUnlessEqual(BarAccount.objects.all()[0].username, "%s-1" % bar_user)
self.failUnlessEqual(Persona.objects.all()[0].accounts.count(), 2)

from django.core import mail

class AdminActionsTest(TestCase):
fixtures = ['admin-views-users.xml', 'admin-views-actions.xml']

Expand Down

0 comments on commit 274aba3

Please sign in to comment.