Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<blockquote> <p>Is there a way to override this behaviour and let the action run anyway?</p> </blockquote> <p>I'm going to say no there is no easy way.</p> <p>If you grep your error message, you see that the code is in <code>django.contrib.admin.options.py</code> and the problem code is deep inside the changelist_view.</p> <pre><code>action_failed = False selected = request.POST.getlist(helpers.ACTION_CHECKBOX_NAME) # Actions with no confirmation if (actions and request.method == 'POST' and 'index' in request.POST and '_save' not in request.POST): if selected: response = self.response_action(request, queryset=cl.get_query_set()) if response: return response else: action_failed = True else: msg = _("Items must be selected in order to perform " "actions on them. No items have been changed.") self.message_user(request, msg) action_failed = True </code></pre> <p>It's also used in the <code>response_action</code> function as well, so you can't just override the changelist_template and use that either -- it's going to be easiest to define your own action-validity checker and runner.</p> <hr> <p>If you really want to use that drop down list, here's an idea with no guarantees.</p> <p>How about defining a new attribute for your selection-less admin actions: <code>myaction.selectionless = True</code></p> <p>Copy the <code>response_action</code> functionality to some extent in your overridden <code>changelist_view</code> that only works on actions with a specific flag specified, then returns the 'real' <code>changelist_view</code></p> <pre><code> # There can be multiple action forms on the page (at the top # and bottom of the change list, for example). Get the action # whose button was pushed. try: action_index = int(request.POST.get('index', 0)) except ValueError: action_index = 0 # Construct the action form. data = request.POST.copy() data.pop(helpers.ACTION_CHECKBOX_NAME, None) data.pop("index", None) # Use the action whose button was pushed try: data.update({'action': data.getlist('action')[action_index]}) except IndexError: # If we didn't get an action from the chosen form that's invalid # POST data, so by deleting action it'll fail the validation check # below. So no need to do anything here pass action_form = self.action_form(data, auto_id=None) action_form.fields['action'].choices = self.get_action_choices(request) # If the form's valid we can handle the action. if action_form.is_valid(): action = action_form.cleaned_data['action'] select_across = action_form.cleaned_data['select_across'] func, name, description = self.get_actions(request)[action] if func.selectionless: func(self, request, {}) </code></pre> <p>You'd still get errors when the 'real' action is called. You could potentially modify the request.POST to remove the action IF the overridden action is called. </p> <p>Other ways involve hacking way too much stuff. I think at least.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload