Dramal
Dramal

Reputation: 177

Handle empty parameters when building url to route

My app has a Product model. Some Products have categories, some do not. In one of my pages I will have this:

{% if row.category %}
    <a href="{{ url_for("details_with_category", category=row.category, title=row.title) }}"> row.prod_title</a>
{% else %}
    <a href="{{ url_for("details_without_category", title=row.title) }}"> row.prod_title</a>
{% endif %}

The views that handles this are:

@app.route('/<category>/<title>', methods=['GET'])
def details_with_category(category, title):
    ....
    return ....

@app.route('/<title>', methods=['GET'])
def details_without_category(title):
    ....
    return ....

Both details_with_category and details_without_category do the exact same thing, just with different urls. Is there a way to combine the views into a single view that takes an optional argument when building the url?

Upvotes: 4

Views: 3184

Answers (1)

davidism
davidism

Reputation: 127400

Apply multiple routes to the same function, passing a default value for optional arguments.

@app.route('/<title>/', defaults={'category': ''})
@app.route('/<category>/<title>')
def details(title, category):
    #...

url_for('details', category='Python', title='Flask')
# /details/Python/Flask

url_for('details', title='Flask')
# /details/Flask

url_for('details', category='', title='Flask')
# the category matches the default so it is ignored
# /details/Flask

A cleaner solution is to just assign a default category to uncategorized products so that the url format is consistent.

Upvotes: 6

Related Questions