user2426062
user2426062

Reputation: 109

Flask: Use URL Binding in URL For?

I have a form in my Flask website which I want to open to a certain page on submit however the link I want uses URL binding which doesn't seem to work well, I'll show you what I mean with the following code.

<form method="POST" action="{{ url_for('topic/<topic>') }}">

I get a build error due to me using the URL topic/<topic> in my url_for.

Is there a way to work around this? The reason for this is because every time someone enters in data to the form, when submitted, I want the user to be redirected to the same page (topic/<topic>) but will an additional /1. I want the number to increase every time the form is submitted so the first time it is submitted I want the URL to be topic/<topic>/1 then the second time topic/<topic>/2 and so forth.

Update 1:

I tried Martijn Pieters method out with the

"url_for('topic', topic='sometopic')"

I didn't include the counter just yet. I also have the

@app.route('/topic/<topic>') 

however when I submit the form the url states

"/topic/topic=The+Fundamental+Ideas+in+Chemistry"

. Before I tried the method it states

"/topic/The+Fundamental+Ideas+in+Chemistry".

Is there a way to remove the 'topic=' part from the url so it looks like it was before?

Update 2:

@app.route('/topic/<topic>')
def questions(topic):
    g.db = connectDB()
    query = 'SELECT question FROM questions WHERE topic=\"' + topic + '\"'
    cur = g.db.execute(query)
    questions = [dict(question=row[0]) for row in cur.fetchall()]
    question = questions[0]['question']
    g.db.close()
    return render_template('topic.html', topic=topic, subject='chemistry', question=question)

Upvotes: 1

Views: 1588

Answers (1)

Martijn Pieters
Martijn Pieters

Reputation: 1124708

You should use the name of the view, not the URL it listens to. Views can listen to multiple URLs.

You registered your view with:

@app.route('/topic/<topic>')
def questions(topic):
    # ...

so the view is registered with the name questions. You need to use questions as the endpoint for url_for(), providing a value for the <topic> URL parameter::

url_for('questions', topic='sometopic')

If you want to pass in additional parameters, you need to make sure your view can accept those:

@app.route('/topic/<topic>')
@app.route('/topic/<topic>/<int:counter>')
def questions(topic, counter=None):
    # ...

and use the extra parameter when building the URL:

url_for('questions', topic='sometopic', counter=some_counter)

You'll also have to think about what it means for someone to submit the form each time. You'll need some form of persistence to store that counter, like a database or a file, or simply a global variable (but that won't scale to multiple processes).

Upvotes: 2

Related Questions