我正在尝试从列表中动态生成Flask中的路由。我想动态生成视图函数和端点,并使用add_url_rule
添加它们。
这就是我想要做的事情,但我得到了一个"映射覆盖"错误:
routes = [
dict(route="/", func="index", page="index"),
dict(route="/about", func="about", page="about")
]
for route in routes:
app.add_url_rule(
route["route"], #I believe this is the actual url
route["page"], # this is the name used for url_for (from the docs)
route["func"]
)
app.view_functions[route["func"]] = return render_template("index.html")
答案 0 :(得分:6)
两种可能的解决方案存在一个问题。之一:
route[func]
直接引用函数,而不是字符串。在这种情况下,您不必为app.view_functions
分配任何内容。或者:
省略app.add_url_rule
的第三个参数,并为app.view_functions[route["page"]]
分配一个函数。代码
return render_template("index.html")
不是一个功能。尝试像
这样的东西def my_func():
return render_template("index.html")
# ...
app.view_functions[route["page"]] = my_func
我推荐第一个选项。
来源:the docs。
在网址中使用变量部分。像这样:
@app.route('/<page>')
def index(page):
if page=='about':
return render_template('about.html') # for example
else:
some_value = do_something_with_page(page) # for example
return render_template('index.html', my_param=some_value)
答案 1 :(得分:5)
对Flask不太熟悉,因此可能有更简洁的方法来执行此操作。 (如果对Flask有所了解的人认为我的方法本质上是错误的,那么如果他们在评论中解释原因,我很乐意删除我的答案。)现在我已经取消了免责声明,这是我的想法:
app.route("/")
是装饰函数。 @
符号只是index = app.route("/")(index)
之类的语法糖。因此,您应该可以做这样的事情......
routes = [
("/", index),
("/about", about)
]
for route, view_func in routes:
view_func = app.route(route)(view_func)
允许您从动态创建的路径和函数创建Flask路径。
答案 2 :(得分:0)
这就是我让它工作的方式@this-vidor和@PZP,获取页面方法是查询sqlite数据库(但它可能是任何数据库),泛型函数def被循环并在我的实际代码中字典列表也从数据库中提取。基本上我完成了我所需要的东西。路线是动态的。我可以在sql中打开和关闭路由,而不必去app.py进行编辑。
defaultPage = "/"
@app.route(defaultPage)
def index():
page = getPage(defaultPage)
return render_template("index.html", page=page)
routes = [
dict(route="/", func="index", page="index"),
dict(route="/about", func="about", page="about")
]
def generic():
rule = request.url_rule
page = getPage(rule)
return render_template('index.html', page=page)
for route in routes:
app.add_url_rule(
route["route"], #I believe this is the actual url
route["page"] # this is the name used for url_for (from the docs)
)
app.view_functions[route["func"]] = generic`