Search code examples
pythonflaskurl-routing

Do optional routing parameters in flask need to be set to "none" in a function?


This code is taken from https://code.visualstudio.com/docs/python/tutorial-flask#_optional-activities to setup a basic webapp using flask and python in visual studio code.

Why does the function "hello_there" have the parameter "name = None"? Shouldn't the function just pass in the name without specifying anything else? To me, the render_template should be setting name to None, since "name = None" is the function parameter. This answer: flask argument in render_template hints that flask overwrites the function parameter. If that's the case, is there a need for the function to have the "name = None" parameter?

@app.route("/hello/")
@app.route("/hello/<name>")
def hello_there(name = None):
    return render_template(
        "hello_there.html",
        name=name,
        date=datetime.now()
    )

Solution

  • name = None is what is called a default argument value and in the case of the function you posted seems to serve as a way to ensure the function hello_there works with or without a name being passed.

    Notice the function decorators:

    @app.route("/hello/")
    @app.route("/hello/<name>")
    

    This means that the expected call for this function is either with or without the parameter name. By setting name default argument to None, we can ensure that if name is never passed the function is still properly able to rendered the page. Notice the following:

    >>> def func(a):
    ...     return a
    
    >>> print(func())
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    TypeError: func() missing 1 required positional argument: 'a'
    

    versus

    >>> def func(a = None):
    ...     return a
    
    >>> print(func())
    None
    

    Notice how on the function you posted name is referenced in the return:

        return render_template(
            "hello_there.html",
            name=name,
            date=datetime.now()
        )
    

    If name is not defined beforehand, then you would see the error listed above. Another thing is -- if I had to guess -- I would assume that within the template hello_there.html there is a context switching for when name is None and for when it is something:

    {% if name %}
        <b> Hello {{ name }}! </b>
    {% else %}
        <b> Hello! </b>
    {% endif %}