summaryrefslogtreecommitdiff
path: root/parts/django/docs/ref/contrib/admin/actions.txt
diff options
context:
space:
mode:
Diffstat (limited to 'parts/django/docs/ref/contrib/admin/actions.txt')
-rw-r--r--parts/django/docs/ref/contrib/admin/actions.txt351
1 files changed, 0 insertions, 351 deletions
diff --git a/parts/django/docs/ref/contrib/admin/actions.txt b/parts/django/docs/ref/contrib/admin/actions.txt
deleted file mode 100644
index 0fab59e..0000000
--- a/parts/django/docs/ref/contrib/admin/actions.txt
+++ /dev/null
@@ -1,351 +0,0 @@
-=============
-Admin actions
-=============
-
-.. versionadded:: 1.1
-
-.. currentmodule:: django.contrib.admin
-
-The basic workflow of Django's admin is, in a nutshell, "select an object,
-then change it." This works well for a majority of use cases. However, if you
-need to make the same change to many objects at once, this workflow can be
-quite tedious.
-
-In these cases, Django's admin lets you write and register "actions" -- simple
-functions that get called with a list of objects selected on the change list
-page.
-
-If you look at any change list in the admin, you'll see this feature in
-action; Django ships with a "delete selected objects" action available to all
-models. For example, here's the user module from Django's built-in
-:mod:`django.contrib.auth` app:
-
-.. image:: _images/user_actions.png
-
-.. warning::
-
- The "delete selected objects" action uses :meth:`QuerySet.delete()
- <django.db.models.QuerySet.delete>` for efficiency reasons, which has an
- important caveat: your model's ``delete()`` method will not be called.
-
- If you wish to override this behavior, simply write a custom action which
- accomplishes deletion in your preferred manner -- for example, by calling
- ``Model.delete()`` for each of the selected items.
-
- For more background on bulk deletion, see the documentation on :ref:`object
- deletion <topics-db-queries-delete>`.
-
-Read on to find out how to add your own actions to this list.
-
-Writing actions
-===============
-
-The easiest way to explain actions is by example, so let's dive in.
-
-A common use case for admin actions is the bulk updating of a model. Imagine a
-simple news application with an ``Article`` model::
-
- from django.db import models
-
- STATUS_CHOICES = (
- ('d', 'Draft'),
- ('p', 'Published'),
- ('w', 'Withdrawn'),
- )
-
- class Article(models.Model):
- title = models.CharField(max_length=100)
- body = models.TextField()
- status = models.CharField(max_length=1, choices=STATUS_CHOICES)
-
- def __unicode__(self):
- return self.title
-
-A common task we might perform with a model like this is to update an
-article's status from "draft" to "published". We could easily do this in the
-admin one article at a time, but if we wanted to bulk-publish a group of
-articles, it'd be tedious. So, let's write an action that lets us change an
-article's status to "published."
-
-Writing action functions
-------------------------
-
-First, we'll need to write a function that gets called when the action is
-trigged from the admin. Action functions are just regular functions that take
-three arguments:
-
- * The current :class:`ModelAdmin`
- * An :class:`~django.http.HttpRequest` representing the current request,
- * A :class:`~django.db.models.QuerySet` containing the set of objects
- selected by the user.
-
-Our publish-these-articles function won't need the :class:`ModelAdmin` or the
-request object, but we will use the queryset::
-
- def make_published(modeladmin, request, queryset):
- queryset.update(status='p')
-
-.. note::
-
- For the best performance, we're using the queryset's :ref:`update method
- <topics-db-queries-update>`. Other types of actions might need to deal
- with each object individually; in these cases we'd just iterate over the
- queryset::
-
- for obj in queryset:
- do_something_with(obj)
-
-That's actually all there is to writing an action! However, we'll take one
-more optional-but-useful step and give the action a "nice" title in the admin.
-By default, this action would appear in the action list as "Make published" --
-the function name, with underscores replaced by spaces. That's fine, but we
-can provide a better, more human-friendly name by giving the
-``make_published`` function a ``short_description`` attribute::
-
- def make_published(modeladmin, request, queryset):
- queryset.update(status='p')
- make_published.short_description = "Mark selected stories as published"
-
-.. note::
-
- This might look familiar; the admin's ``list_display`` option uses the
- same technique to provide human-readable descriptions for callback
- functions registered there, too.
-
-Adding actions to the :class:`ModelAdmin`
------------------------------------------
-
-Next, we'll need to inform our :class:`ModelAdmin` of the action. This works
-just like any other configuration option. So, the complete ``admin.py`` with
-the action and its registration would look like::
-
- from django.contrib import admin
- from myapp.models import Article
-
- def make_published(modeladmin, request, queryset):
- queryset.update(status='p')
- make_published.short_description = "Mark selected stories as published"
-
- class ArticleAdmin(admin.ModelAdmin):
- list_display = ['title', 'status']
- ordering = ['title']
- actions = [make_published]
-
- admin.site.register(Article, ArticleAdmin)
-
-That code will give us an admin change list that looks something like this:
-
-.. image:: _images/article_actions.png
-
-That's really all there is to it! If you're itching to write your own actions,
-you now know enough to get started. The rest of this document just covers more
-advanced techniques.
-
-Advanced action techniques
-==========================
-
-There's a couple of extra options and possibilities you can exploit for more
-advanced options.
-
-Actions as :class:`ModelAdmin` methods
---------------------------------------
-
-The example above shows the ``make_published`` action defined as a simple
-function. That's perfectly fine, but it's not perfect from a code design point
-of view: since the action is tightly coupled to the ``Article`` object, it
-makes sense to hook the action to the ``ArticleAdmin`` object itself.
-
-That's easy enough to do::
-
- class ArticleAdmin(admin.ModelAdmin):
- ...
-
- actions = ['make_published']
-
- def make_published(self, request, queryset):
- queryset.update(status='p')
- make_published.short_description = "Mark selected stories as published"
-
-Notice first that we've moved ``make_published`` into a method and renamed the
-`modeladmin` parameter to `self`, and second that we've now put the string
-``'make_published'`` in ``actions`` instead of a direct function reference. This
-tells the :class:`ModelAdmin` to look up the action as a method.
-
-Defining actions as methods gives the action more straightforward, idiomatic
-access to the :class:`ModelAdmin` itself, allowing the action to call any of the
-methods provided by the admin.
-
-.. _custom-admin-action:
-
-For example, we can use ``self`` to flash a message to the user informing her
-that the action was successful::
-
- class ArticleAdmin(admin.ModelAdmin):
- ...
-
- def make_published(self, request, queryset):
- rows_updated = queryset.update(status='p')
- if rows_updated == 1:
- message_bit = "1 story was"
- else:
- message_bit = "%s stories were" % rows_updated
- self.message_user(request, "%s successfully marked as published." % message_bit)
-
-This make the action match what the admin itself does after successfully
-performing an action:
-
-.. image:: _images/article_actions_message.png
-
-Actions that provide intermediate pages
----------------------------------------
-
-By default, after an action is performed the user is simply redirected back
-to the original change list page. However, some actions, especially more
-complex ones, will need to return intermediate pages. For example, the
-built-in delete action asks for confirmation before deleting the selected
-objects.
-
-To provide an intermediary page, simply return an
-:class:`~django.http.HttpResponse` (or subclass) from your action. For
-example, you might write a simple export function that uses Django's
-:doc:`serialization functions </topics/serialization>` to dump some selected
-objects as JSON::
-
- from django.http import HttpResponse
- from django.core import serializers
-
- def export_as_json(modeladmin, request, queryset):
- response = HttpResponse(mimetype="text/javascript")
- serializers.serialize("json", queryset, stream=response)
- return response
-
-Generally, something like the above isn't considered a great idea. Most of the
-time, the best practice will be to return an
-:class:`~django.http.HttpResponseRedirect` and redirect the user to a view
-you've written, passing the list of selected objects in the GET query string.
-This allows you to provide complex interaction logic on the intermediary
-pages. For example, if you wanted to provide a more complete export function,
-you'd want to let the user choose a format, and possibly a list of fields to
-include in the export. The best thing to do would be to write a small action
-that simply redirects to your custom export view::
-
- from django.contrib import admin
- from django.contrib.contenttypes.models import ContentType
- from django.http import HttpResponseRedirect
-
- def export_selected_objects(modeladmin, request, queryset):
- selected = request.POST.getlist(admin.ACTION_CHECKBOX_NAME)
- ct = ContentType.objects.get_for_model(queryset.model)
- return HttpResponseRedirect("/export/?ct=%s&ids=%s" % (ct.pk, ",".join(selected)))
-
-As you can see, the action is the simple part; all the complex logic would
-belong in your export view. This would need to deal with objects of any type,
-hence the business with the ``ContentType``.
-
-Writing this view is left as an exercise to the reader.
-
-.. _adminsite-actions:
-
-Making actions available site-wide
-----------------------------------
-
-.. method:: AdminSite.add_action(action[, name])
-
- Some actions are best if they're made available to *any* object in the admin
- site -- the export action defined above would be a good candidate. You can
- make an action globally available using :meth:`AdminSite.add_action()`. For
- example::
-
- from django.contrib import admin
-
- admin.site.add_action(export_selected_objects)
-
- This makes the `export_selected_objects` action globally available as an
- action named `"export_selected_objects"`. You can explicitly give the action
- a name -- good if you later want to programatically :ref:`remove the action
- <disabling-admin-actions>` -- by passing a second argument to
- :meth:`AdminSite.add_action()`::
-
- admin.site.add_action(export_selected_objects, 'export_selected')
-
-.. _disabling-admin-actions:
-
-Disabling actions
------------------
-
-Sometimes you need to disable certain actions -- especially those
-:ref:`registered site-wide <adminsite-actions>` -- for particular objects.
-There's a few ways you can disable actions:
-
-Disabling a site-wide action
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. method:: AdminSite.disable_action(name)
-
- If you need to disable a :ref:`site-wide action <adminsite-actions>` you can
- call :meth:`AdminSite.disable_action()`.
-
- For example, you can use this method to remove the built-in "delete selected
- objects" action::
-
- admin.site.disable_action('delete_selected')
-
- Once you've done the above, that action will no longer be available
- site-wide.
-
- If, however, you need to re-enable a globally-disabled action for one
- particular model, simply list it explicitly in your ``ModelAdmin.actions``
- list::
-
- # Globally disable delete selected
- admin.site.disable_action('delete_selected')
-
- # This ModelAdmin will not have delete_selected available
- class SomeModelAdmin(admin.ModelAdmin):
- actions = ['some_other_action']
- ...
-
- # This one will
- class AnotherModelAdmin(admin.ModelAdmin):
- actions = ['delete_selected', 'a_third_action']
- ...
-
-
-Disabling all actions for a particular :class:`ModelAdmin`
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-If you want *no* bulk actions available for a given :class:`ModelAdmin`, simply
-set :attr:`ModelAdmin.actions` to ``None``::
-
- class MyModelAdmin(admin.ModelAdmin):
- actions = None
-
-This tells the :class:`ModelAdmin` to not display or allow any actions,
-including any :ref:`site-wide actions <adminsite-actions>`.
-
-Conditionally enabling or disabling actions
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-.. method:: ModelAdmin.get_actions(request)
-
- Finally, you can conditionally enable or disable actions on a per-request
- (and hence per-user basis) by overriding :meth:`ModelAdmin.get_actions`.
-
- This returns a dictionary of actions allowed. The keys are action names, and
- the values are ``(function, name, short_description)`` tuples.
-
- Most of the time you'll use this method to conditionally remove actions from
- the list gathered by the superclass. For example, if I only wanted users
- whose names begin with 'J' to be able to delete objects in bulk, I could do
- the following::
-
- class MyModelAdmin(admin.ModelAdmin):
- ...
-
- def get_actions(self, request):
- actions = super(MyModelAdmin, self).get_actions(request)
- if request.user.username[0].upper() != 'J':
- del actions['delete_selected']
- return actions
-
-