允许用户删除帐户会导致Flask中出现400错误请求

时间:2018-08-15 06:45:55

标签: python post flask delete-row http-status-code-400

我在设置用户帐户删除选项时遇到问题。我已经设置了一个Bootstrap模态来弹出以确保安全,并且我想要“删除”按钮从数据库中删除当前用户的帐户,注销该用户,并通过Flash消息将该用户重定向到首页。但是,当我单击按钮时,它抛出400错误的请求错误。我不知道原因是POST方法还是其他原因,所以我在这里寻求您的帮助。我在应用程序中使用PostgreSQL以及SQLAlchemy和Flask-Login(用于current_user)。这是我第一次设置类似的内容,如果我的问题不够清楚,请告诉我,以便我提供更多详细信息。另外,如果您对如何优化此问题有任何建议,我将不胜感激。这是相关的代码:

模式中的按钮:

<form action="{{ url_for('user.delete_account') }}" method="POST">
  <input type="submit" id="delete" name="delete" value="Delete" class="btn btn-danger">
</form>

路由和删除功能:

@user.route('/delete', methods=['POST'])
@login_required
def delete_account():
    if request.method == 'POST':
        if request.form['delete'] == 'Delete':

            current_user.delete()

            flash('Your account has been successfully deleted.', 'success')
            return redirect(url_for('core.home'))

我真的希望我的问题足够清楚,因为我连续10多个小时都被困住了,我需要帮助。预先感谢。

2 个答案:

答案 0 :(得分:1)

找到解决方案:

因此,基本上,我花了一些时间研究代码并找到了解决方案。这是相关代码:

首先,我创建了一个带有隐藏CSRF令牌的Jinja2宏:

{%- macro form_tag(endpoint, fid='', css_class='', method='post') -%}
  <form action="{{ url_for(endpoint, **kwargs) }}" method="{{ method }}"
        id="{{ fid }}" class="{{ css_class }}" role="form">
    {{ form.hidden_tag() }}
    {{ caller () }}
  </form>
{%- endmacro -%}

之后,我创建了最简单的表格:

from flask_wtf import Form
from wtforms import SubmitField


class DeleteUserForm(Form):
    delete = SubmitField('Delete')

此后,我将其添加到Bootstrap模式:

{% import 'macros/form.html' as f with context %}

{% call f.form_tag('user.delete') %}
  <button type="submit" class="btn btn-danger">Delete</button>
{% endcall %}

最后,我在views.py文件中修改了路线:

@user.route('/settings/delete', methods=['POST'])
@login_required
def delete():
    form = DeleteUserForm()

    if form.validate_on_submit():
        current_user.delete()

        flash('Your account has been successfully deleted. Hope to see you again.', 'success')
        return redirect(url_for('user.login'))

    return render_template('user/login.html', form=form)

此解决方案是我能做到的最好的方法。我希望这也会对其他人有所帮助。哦,我几乎忘记了,因为我正在编辑settings.html文件,所以我还必须在页面的form=form路由中传递/settings参数:

@user.route('/settings')
@login_required
def settings():
    form = DeleteUserForm()
    return render_template('user/settings.html', form=form)

仅此而已。多亏那些也发布了答案的人,我对此表示赞赏。

答案 1 :(得分:0)

编辑:事实证明,该问题可能是可能来自全局安装的CSRF保护层(例如Flask-WTF之类)。如果您甚至没有接触到处理程序,则进行调试将极大地帮助您创建最小的可重复示例。


原始最佳答案:您几乎肯定会从request.form['delete']收到400 Bad Request错误-当您尝试从{{1 }}未发送到服务器(引发的错误也是request.{form, args, values}的子类型,在相同情况下普通Python字典会引发该错误:

KeyError

所以现在的问题是,“为什么在表单请求中没有'删除'?”。那里的答案几乎可以肯定是因为您正在用JavaScript捕获此表单的Submit事件并以编程方式提交该表单……而不包括按钮的值。包含必要的参数,或者根本不检查表单值(甚至不检查方法,因为您已经将路由限制为仅接收({ "x": 123 })["y"] # Raises a KeyError request.form["not-in-form"] # Raises a BadRequest error 。)

POST