-
-
Notifications
You must be signed in to change notification settings - Fork 31.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Made a bunch of improvements to admin actions. Be warned: this includ…
…es one minor but BACKWARDS-INCOMPATIBLE change. These changes are: * BACKWARDS-INCOMPATIBLE CHANGE: action functions and action methods now share the same signature: `(modeladmin, request, queryset)`. Actions defined as methods stay the same, but if you've defined an action as a standalone function you'll now need to add that first `modeladmin` argument. * The delete selected action is now a standalone function registered site-wide; this makes disabling it easy. * Fixed #10596: there are now official, documented `AdminSite` APIs for dealing with actions, including a method to disable global actions. You can still re-enable globally-disabled actions on a case-by-case basis. * Fixed #10595: you can now disable actions for a particular `ModelAdmin` by setting `actions` to `None`. * Fixed #10734: actions are now sorted (by name). * Fixed #10618: the action is now taken from the form whose "submit" button you clicked, not arbitrarily the last form on the page. * All of the above is documented and tested. git-svn-id: http://code.djangoproject.com/svn/django/trunk@10408 bcc190cf-cafb-0310-a4f2-bffc1f526a37
- Loading branch information
Showing
9 changed files
with
367 additions
and
131 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Original file line | Diff line number | Diff line change |
---|---|---|---|
@@ -0,0 +1,81 @@ | |||
""" | |||
Built-in, globally-available admin actions. | |||
""" | |||
|
|||
from django import template | |||
from django.core.exceptions import PermissionDenied | |||
from django.contrib.admin import helpers | |||
from django.contrib.admin.util import get_deleted_objects, model_ngettext | |||
from django.shortcuts import render_to_response | |||
from django.utils.encoding import force_unicode | |||
from django.utils.html import escape | |||
from django.utils.safestring import mark_safe | |||
from django.utils.text import capfirst | |||
from django.utils.translation import ugettext_lazy, ugettext as _ | |||
|
|||
def delete_selected(modeladmin, request, queryset): | |||
""" | |||
Default action which deletes the selected objects. | |||
This action first displays a confirmation page whichs shows all the | |||
deleteable objects, or, if the user has no permission one of the related | |||
childs (foreignkeys), a "permission denied" message. | |||
Next, it delets all selected objects and redirects back to the change list. | |||
""" | |||
opts = modeladmin.model._meta | |||
app_label = opts.app_label | |||
|
|||
# Check that the user has delete permission for the actual model | |||
if not modeladmin.has_delete_permission(request): | |||
raise PermissionDenied | |||
|
|||
# Populate deletable_objects, a data structure of all related objects that | |||
# will also be deleted. | |||
|
|||
# deletable_objects must be a list if we want to use '|unordered_list' in the template | |||
deletable_objects = [] | |||
perms_needed = set() | |||
i = 0 | |||
for obj in queryset: | |||
deletable_objects.append([mark_safe(u'%s: <a href="%s/">%s</a>' % (escape(force_unicode(capfirst(opts.verbose_name))), obj.pk, escape(obj))), []]) | |||
get_deleted_objects(deletable_objects[i], perms_needed, request.user, obj, opts, 1, modeladmin.admin_site, levels_to_root=2) | |||
i=i+1 | |||
|
|||
# The user has already confirmed the deletion. | |||
# Do the deletion and return a None to display the change list view again. | |||
if request.POST.get('post'): | |||
if perms_needed: | |||
raise PermissionDenied | |||
n = queryset.count() | |||
if n: | |||
for obj in queryset: | |||
obj_display = force_unicode(obj) | |||
modeladmin.log_deletion(request, obj, obj_display) | |||
queryset.delete() | |||
modeladmin.message_user(request, _("Successfully deleted %(count)d %(items)s.") % { | |||
"count": n, "items": model_ngettext(modeladmin.opts, n) | |||
}) | |||
# Return None to display the change list page again. | |||
return None | |||
|
|||
context = { | |||
"title": _("Are you sure?"), | |||
"object_name": force_unicode(opts.verbose_name), | |||
"deletable_objects": deletable_objects, | |||
'queryset': queryset, | |||
"perms_lacking": perms_needed, | |||
"opts": opts, | |||
"root_path": modeladmin.admin_site.root_path, | |||
"app_label": app_label, | |||
'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME, | |||
} | |||
|
|||
# Display the confirmation page | |||
return render_to_response(modeladmin.delete_confirmation_template or [ | |||
"admin/%s/%s/delete_selected_confirmation.html" % (app_label, opts.object_name.lower()), | |||
"admin/%s/delete_selected_confirmation.html" % app_label, | |||
"admin/delete_selected_confirmation.html" | |||
], context, context_instance=template.RequestContext(request)) | |||
|
|||
delete_selected.short_description = ugettext_lazy("Delete selected %(verbose_name_plural)s") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.