动态生成Flask路线

时间:2016-07-17 03:14:32

标签: python flask

我正在尝试从列表中动态生成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")

3 个答案:

答案 0 :(得分:6)

两种可能的解决方案存在一个问题。之一:

  1. route[func]直接引用函数,而不是字符串。在这种情况下,您不必为app.view_functions分配任何内容。
  2. 或者:

    1. 省略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
      
    2. 我推荐第一个选项。

      来源: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`