My favorites | Sign in
Project Logo
                
Search
for
Updated Sep 18, 2008 by exogen
Labels: Featured, Phase-Deploy
GettingStarted  

Installation

  1. Download a release or check out the source code or use easy_install:
  2. $ easy_install django-batchadmin
  3. Install the batchadmin app somewhere your project can import it. If you used the command above, this part is probably done.
  4. Link or copy batchadmin/media to somewhere under MEDIA_ROOT, like MEDIA_ROOT/batchadmin:
  5. $ ln -s /path/to/batchadmin/media /path/to/MEDIA_ROOT/batchadmin
  6. Add 'batchadmin' to INSTALLED_APPS in your project's settings.py file:
  7. INSTALLED_APPS = (
        'batchadmin',
        'django.contrib.admin',
        ...
    )

Configuration

batchadmin checks two optional settings in your project's settings.py file:

BATCHADMIN_MEDIA_PREFIX

The URL path, relative to MEDIA_URL, where batchadmin's media files are available. Should end with and not begin with a forward slash (/).

Default: "batchadmin/" (batchadmin assumes you made its media available at MEDIA_URL/batchadmin/.)

BATCHADMIN_JQUERY_JS

The URL path, relative to MEDIA_URL, where jQuery lives. batchadmin's JavaScript is unobtrusive -- without it you just lose Select all and row highlighting. Should not begin with a forward slash (/).

Default: BATCHADMIN_MEDIA_PREFIX + "js/jquery.js" (batchadmin will use its own bundled version of jQuery.)

Basic Usage

The simplest possible example:

from django.contrib import admin
from batchadmin.admin import BatchModelAdmin
from yourapp.models import YourModel

admin.site.register(YourModel, BatchModelAdmin)

Or, if you already have ModelAdmin subclasses defined, change this:

class YourModelAdmin(admin.ModelAdmin):
    ...

... to this:

from batchadmin.admin import BatchModelAdmin

class YourModelAdmin(BatchModelAdmin):
    ...

Troubleshooting

Media not loaded (Select all not working, unstyled action form)

batchadmin's media (CSS and JavaScript) was not properly copied or configured (see Step 3 above).

Template not found

batchadmin was not added to your INSTALLED_APPS setting (see Step 4 above).

Adding Actions

By default, BatchModelAdmin only provides one action, delete_selected. Subclass BatchModelAdmin to add actions like so:

from django.contrib import admin
from batchadmin.admin import BatchModelAdmin, CHECKBOX_NAME
from yourapp.models import YourModel

class YourModelAdmin(BatchModelAdmin):
    batch_actions = ['delete_selected', 'transmogrify']

    def transmogrify(self, request, changelist):
        selected = request.POST.getlist(CHECKBOX_NAME)
        objects = changelist.get_query_set().filter(pk__in=selected)
        for obj in objects:
            obj.transmogrify()
            obj.save()
        self.message_user(request, "Objects transmogrified.")

admin.site.register(YourModel, YourModelAdmin)

Changing the action description

Set the short_description attribute of your action's method to the desired description. Two formatting variables are interpolated when the action list is rendered: verbose_name and verbose_name_plural (using one of these is not required).

    transmogrify.short_description = "Transmogrify selected %(verbose_name_plural)s"

Creating actions with an intermediate page

By default, the user is returned to the change list after performing an action. However, if your action method returns an HttpResponse object, that is returned instead of the normal redirect. Best practice is to redirect to your intermediate page and pass the selected objects in the query string (this is safe, as nothing is being modified yet). Below is an example merge_selected action with an intermediate page.

In your BatchModelAdmin subclass:

    def merge_selected(self, request, changelist):
        selected = request.POST.getlist(CHECKBOX_NAME)
        if selected:
            qs = changelist.get_query_string({'pk__in': ','.join(selected)})
            return HttpResponseRedirect("merge/" + qs)

Give your intermediate page an entry in urls.py:

urlpatterns = patterns('yourapp.views',
    url(r'admin/([^/]+)/([^/]+)/merge/$', 'merge_view')
)

In your views.py:

from django.http import HttpResponseRedirect
from django.db import models
from batchadmin.util import get_changelist

def merge_view(request, app_label, model_name):
    model = models.get_model(app_label, model_name)
    changelist = get_changelist(request, model)
    objects = changelist.get_query_set()
    # The objects have already been filtered with the query string.
    if request.method == 'POST':
        # Perform the action...
        # Redirecting to "../" will go back to the change list.
        return HttpResponseRedirect("../")
    else:
        # Render the intermediate page, presumably containing a
        # form that POSTs to this same view.

Customizing BatchModelAdmin Behavior

Besides batch_actions, BatchModelAdmin subclasses may specify several attributes to change the default behavior:


Comment by davidgrant, Sep 18, 2008

Sorry but this wasn't obvious to me right away. I have a lot of custom admin classes and I didn't see any example of how to add batch capability to them. It's easy though, just inherit from BatchModelAdmin? instead of ModelAdmin?

Comment by exogen, Sep 18, 2008

Thanks for the note, I've updated the Basic Usage section.

Comment by dane.springmeyer, Sep 30, 2008

First of all, nice project.

Second, I use GeoDjango? which has its own various ModelAdmin? subclasses (GeoModelAdmin? and OSMGeoAdmin). It was easy enough to go in and switch out the several imports from django.contrib.admin to be from django.contrib.gis.admin (within the batchadmin code). But, I'm curious if you've given thought to some kind of settings switch like BATCHADMIN_INHERIT_FROM = 'django.contrib.gis.admin' # or any other custom admin?

Anyway, I'll attach my patch file to an issue to give you a sense of getting batchadmin running alongside geodjango.

Comment by joshbloom, Oct 15, 2008

I'm seeing the following error after trying the simple setup:

django.core.exceptions.ImproperlyConfigured?: BatchModelAdmin.list_display[0] refers to batchadmin_checkbox that is neither a field, method or property of model myModel.

Any ideas as to what may be causing this?

Comment by st...@telcotec.se, Oct 23, 2008

Brilliant app! Thanks! /stava

Comment by jonathan.sabo, Dec 22, 2008

Does this work with in-line edited models?

Comment by hounsell.al, Feb 03, 2009

I keep getting a TemplateSyntaxError? that says my object has no attribute 'batchadmin_checkbox' I've set everything up according to directions... Any help?

Comment by gatosinduenio, Feb 11, 2009

nice project I didnt want checkbox list and i modified like that:

In admin.py:

class BatchModelAdmin(admin.ModelAdmin):
    change_list_template = "batchadmin/change_list.html"
    list_display = list(admin.ModelAdmin.list_display)
    batchadmin_show_checkbox = True
...
    def __init__(self, *args, **kwargs):
        super(BatchModelAdmin, self).__init__(*args, **kwargs)
        if self.batchadmin_show_checkbox:
            self.list_display = list(self.list_display)
            self.list_display.insert(0, 'batchadmin_checkbox')
...
        context = {
            'batchadmin_action_form': action_form,
            'batchadmin_media': action_form.media,
            'batchadmin_on_top': self.actions_on_top,
            'batchadmin_on_bottom': self.actions_on_bottom,
            'batchadmin_show_checkbox': self.batchadmin_show_checkbox,
        }

in actions.html:

    {% if batchadmin_show_checkbox %}
        <button type="button" class="all" name="select_all" title="Select all {{ cl.opts.verbose_name_plural }}">&#x2713; Select all</button>
        <button type="button" class="all" name="deselect_all" title="Deselect all {{ cl.opts.verbose_name_plural }}">&#x2718; Deselect all</button>
    {% endif %}

i hope it will be usefull

Comment by vgavro, May 18, 2009

brilliant project! great respect to developers.


Sign in to add a comment
Hosted by Google Code