title: Flask Confirm Action
body: <p>I'm creating a site using the Flask framework, and am implementing a confirmation page for (mainly administrative) actions; i.e. deleting a user.</p>
  
  <p>My current method (detailed below) works, but feels quite clunky and seems like a huge amount of work for a simple task. Is there a more optimal solution to this?</p>
  
  <p>Currently I have a route to initiate the action:</p>
  
  <pre><code>@admin.route('/user/&lt;int:user_id&gt;/delete', methods=['GET'])
  @login_required
  @admin_required
  def del_user(user_id):
      user = User.query.get_or_404(user_id)
      desc = "delete"
      subject = user.username
      action = 'admin.do_del_user'
      next = url_for('admin.get_user', user_id=user.id)
      return redirect(url_for('main._confirm', desc=desc, subject=subject, action=action, next=next, user_id=user.id))
  </code></pre>
  
  <p>Which redirects over to the confirm route:</p>
  
  <pre><code>@main.route('/confirm', methods=['GET', 'POST'])
  def _confirm():
      form = Confirm()
      kwargs = {}
      for arg in request.args:
          if arg != 'action' or arg != 'desc' or arg != 'subject':
              kwargs[arg] = request.args[arg]
      action = request.args.get('action')
      desc = request.args.get('desc')
      subject = request.args.get('subject')
  
      if action is None:
          abort(404)
  
      if form.validate_on_submit():
          return redirect(url_for(action, confirm=form.confirm.data, **kwargs))
      return render_template('_confirm.html', form=form, desc=desc, subject=subject)
  </code></pre>
  
  <p>Which then redirects again to do the actual action after validating the confirmation form:</p>
  
  <pre><code>@admin.route('/user/&lt;int:user_id&gt;/do_delete', methods=['GET'])
  @login_required
  @admin_required
  def do_del_user(user_id):
      confirm = request.args.get('confirm')
      next = request.args.get('next')
      if confirm:
          user = User.query.get_or_404(user_id)
          db.session.delete(user)
          db.session.commit()
      return redirect(next)
  </code></pre>
  
  <p>I hope that makes sense! Just to note, <em>desc</em> and <em>subject</em> are passed for the confirmation template, and the <em>kwargs</em> is just to catch anything url_for() needs in building the urls.</p>