Dynamically generate Flask routes

前端 未结 3 1055
渐次进展
渐次进展 2021-01-05 10:50

I am trying to dynamically generate routes in Flask from a list. I want to dynamically generate view functions and endpoints and add them with add_url_rule.

相关标签:
3条回答
  • 2021-01-05 11:38

    Not too familiar with Flask, so it is possible that there is a cleaner way to do this. (If someone who is knowledgeable about Flask thinks that my method is inherently wrong, I'll gladly delete my answer if they explain why in a comment.) Now that I got that disclaimer out of the way, here are my thoughts:

    app.route("/") is a decorator function. The @ notation is just syntactic sugar for something like index = app.route("/")(index). Therefore, you should be able to do something like this...

    routes = [
        ("/", index),
        ("/about", about)
    ]
    for route, view_func in routes:
        view_func = app.route(route)(view_func)
    

    which would allow you to create the Flask routes from dynamically created routes and functions.

    0 讨论(0)
  • 2021-01-05 11:38

    This is how i got it to work @this-vidor and @PZP, the get page method is querying an sqlite db (but it could be any db), the generic function def is being looped over and in my actual code list of dictionaries is also being pulled from a db. So basically what I accomplished what I needed. The routes are dynamic. I can turn the routes on and off in the sql with out having to go to app.py to edit them.

    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`
    
    0 讨论(0)
  • 2021-01-05 11:46

    You have one problem with two possible solutions. Either:

    1. Have route[func] directly reference a function, not a string. In this case, you don't have to assign anything to app.view_functions.

    Or:

    1. Leave out the third argument of app.add_url_rule, and assign a function to app.view_functions[route["page"]]. The code

      return render_template("index.html")
      

      is not a function. Try something like

      def my_func():
          return render_template("index.html")
      # ...
      app.view_functions[route["page"]] = my_func
      

    I'd recommend the first option.

    Source: the docs.


    Alternate solution:

    Use variable parts in the URL. Something like this:

    @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)
    
    0 讨论(0)
提交回复
热议问题