Take the 2-minute tour ×

I have a finite state machine (django-fsm) which allows an object to go from a source state into one of several target states. I can add all the actions in a dictionary like:

ACTIONS { 'button_1': action1,
          'button_2': action2,

This translates in a form with a submit button for each state.

  {% for n,m in object.get_available_current_state_transitions %}
      <input type="submit" class="btn" value="{{ n|get_action|capfirst }}"
             name="button_{{n}}" />

  <input type="submit" class="btn primary" value="Save">
  <a class="btn" onclick="javascript:history.go(-1)">Cancel</a>

This usually results in more than 3 buttons.

Clicking a button results in a specific action, defined in my case in the model class.

Now, I know I can get the clicked button in the request.POST dictionary, but this would result in a cascade if like:

  if 'button_1' in request.POST:
  elif 'button_2' in request.POST:

Is there any way to get the button pressed separately (ideally from the request object) in a variable so I can have something like


? In other words, is there any way to obtain the clicked button outside the POST dictionary?

PS: I've looked other replies on the "multiple buttons" question, but all offer request.POST as answer.

share|improve this question

2 Answers 2

up vote 2 down vote accepted

If all of the actions and strings are already in your view, why don't you just iterate over that actions dict?

for key, value in ACTIONS.items():
    if key in request.POST:

Just make your button names very unlikely to be used as a regular form field name.

A few alternatives: use javascript to handle the submission and have it set a single form field such as "action".

Use more unique keys and filter through request.POST.keys() with a regex pattern or string comparison.

action = [x for x in request.POST.keys() if 'FAIRLY_UNIQUE_BUTTON_PREFIX' in x]

if action:
share|improve this answer
The very thing I'm trying to avoid is the double nesting... I was hoping there's another way. –  Laur Ivan Jan 24 '12 at 7:48
It looks like I'll have to use something equivalent to the last code snippet for the time being :) Thanks for the prefix idea! –  Laur Ivan Jan 24 '12 at 11:04

I don't think so directly, but a couple workarounds could be:

  1. Send your buttons to different urlconfs with some variable (like a three letter arg). All of these confs point to the same view taking this three letter arg as an argument, which then knows what to do. This might still result in a cascade if else though.

  2. Or, send them to different views all together.

  3. You could try doing something ajaxy. The data will still be in a post dict, but you will have more control over how the post dict is structured.

I'm also assuming GET isn't an option for any of these (yet that still results in if else structures.)

share|improve this answer
How can I do 1 or 2? I thought the form URL is actually defined by its action attribute..? –  Laur Ivan Jan 24 '12 at 7:50
After looking at things, it looks like all of the above imply some javascript. Now I'm trying to avoid that, but I'll keep it in mind for a more advanced implementation. –  Laur Ivan Jan 24 '12 at 11:00
@equinoxel you can send to a specific url by using the action element. Taking from your example <input action='new_url' type="submit" class="btn primary" value="Save"> –  James R Jan 24 '12 at 14:49
Wow, HTML5 has indeed formaction, but according to w3schools it's not supported in IE :( –  Laur Ivan Jan 24 '12 at 16:18

Your Answer


