Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django admin action without selecting objects

Is it possible to create a custom admin action for the django admin that doesn't require selecting some objects to run it on?

If you try to run an action without selecting objects, you get the message:

Items must be selected in order to perform actions on them. No items have been changed. 

Is there a way to override this behaviour and let the action run anyway?

like image 335
m000 Avatar asked Dec 21 '10 15:12

m000


2 Answers

The accepted answer didn't work for me in django 1.6, so I ended up with this:

from django.contrib import admin from django.contrib.admin.helpers import ACTION_CHECKBOX_NAME  class MyModelAdmin(admin.ModelAdmin):      ....      def changelist_view(self, request, extra_context=None):         if 'action' in request.POST and request.POST['action'] == 'your_action_here':             if not request.POST.getlist(ACTION_CHECKBOX_NAME):                 post = request.POST.copy()                 for u in MyModel.objects.all():                     post.update({ACTION_CHECKBOX_NAME: str(u.id)})                 request._set_post(post)         return super(MyModelAdmin, self).changelist_view(request, extra_context) 

When my_action is called and nothing is selected, select all MyModel instances in db.

like image 124
AndyTheEntity Avatar answered Sep 23 '22 08:09

AndyTheEntity


I wanted this but ultimately decided against using it. Posting here for future reference.


Add an extra property (like acts_on_all) to the action:

def my_action(modeladmin, request, queryset):     pass my_action.short_description = "Act on all %(verbose_name_plural)s" my_action.acts_on_all = True 

 

In your ModelAdmin, override changelist_view to check for your property.

If the request method was POST, and there was an action specified, and the action callable has your property set to True, modify the list representing selected objects.

def changelist_view(self, request, extra_context=None):     try:         action = self.get_actions(request)[request.POST['action']][0]         action_acts_on_all = action.acts_on_all     except (KeyError, AttributeError):         action_acts_on_all = False      if action_acts_on_all:         post = request.POST.copy()         post.setlist(admin.helpers.ACTION_CHECKBOX_NAME,                      self.model.objects.values_list('id', flat=True))         request.POST = post      return admin.ModelAdmin.changelist_view(self, request, extra_context) 
like image 33
Anson Avatar answered Sep 23 '22 08:09

Anson