4

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?

1 Answer 1

6

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.