gpt4 book ai didi

python - flask 确认 Action

转载 作者:太空宇宙 更新时间:2023-11-03 13:40:09 25 4
gpt4 key购买 nike

我正在使用 Flask 框架创建一个站点,并且正在为(主要是管理)操作实现一个确认页面;即删除用户。

我目前的方法(详见下文)有效,但感觉很笨拙,而且对于一个简单的任务来说似乎需要大量工作。是否有更优的解决方案?

目前我有一个启动操作的路径:

@admin.route('/user/<int:user_id>/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))

重定向到确认路由:

@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)

然后在验证确认表单后再次重定向以执行实际操作:

@admin.route('/user/<int:user_id>/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)

我希望这是有道理的!请注意,descsubject 是为确认模板传递的,kwargs 只是为了捕获 url_for() 在构建网址。

最佳答案

我认为最简单的方法是在客户端进行确认。它在视觉上并不漂亮,但是 window.confirm('Are you sure?'); 会做同样的事情。

也就是说,如果您只是在寻找服务器端解决方案,您可以创建一个 @confirmation_required 装饰器来处理重定向。然后,您可以用它包装您需要确认的任何 View ,传入一个函数以获取您想要显示的消息。

from functools import wraps
from urllib import urlencode, quote, unquote
from flask import Flask, request, redirect, url_for, render_template

app = Flask(__name__)

def confirmation_required(desc_fn):
def inner(f):
@wraps(f)
def wrapper(*args, **kwargs):
if request.args.get('confirm') != '1':
desc = desc_fn()
return redirect(url_for('confirm',
desc=desc, action_url=quote(request.url)))
return f(*args, **kwargs)
return wrapper
return inner

@app.route('/confirm')
def confirm():
desc = request.args['desc']
action_url = unquote(request.args['action_url'])

return render_template('_confirm.html', desc=desc, action_url=action_url)

def you_sure():
return "Are you sure?"

@app.route('/')
@confirmation_required(you_sure)
def hello_world():
return 'Hello World!'


if __name__ == '__main__':
app.run(debug=True)

_confirm.html:

<html xmlns="http://www.w3.org/1999/html">
<body>
<h1>{{ desc }}</h1>
<form action="{{ action_url }}" method="GET">
<input type="hidden" name="confirm" value="1">
<input type="submit" value="Yes">
</form>
</body>
</html>

请注意,执行此重定向仅在您包装的 View 接受 GET 时才有效,并且允许 GET 用于任何修改数据的操作并不是一个好主意。 (参见 Why shouldn't data be modified on an HTTP GET request?)

更新:如果您真的想要一个适用于 POST 的通用解决方案,我会切换到基于类的 View 并创建一个处理确认逻辑的混入。像这样的东西:

class ConfirmationViewMixin(object):
confirmation_template = '_confirm.html'

def get_confirmation_context(self):
# implement this in your view class
raise NotImplementedError()

def post(self):
if request.args.get('confirm') == '1':
return super(ConfirmationViewMixin, self).post()

return render_template(
self.confirmation_template, **self.get_confirmation_context())

(未经测试,不确定结果如何。但你明白了。)

关于python - flask 确认 Action ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32911578/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com