1

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)
Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
user2426062
  • 109
  • 4
  • 15
  • You need to define how you are counting form submissions. Does your view configuration actually accept that parameter? E.g. have you registered the `/topic//` URL? – Martijn Pieters Feb 27 '15 at 19:02

1 Answers1

2

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).

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
  • Thanks for you response, I tried your method out with the "url_for('topic', topic='sometopic')", I didn't include the counter just yet. I also have the @app.route('/topic/') however when I submit the form the url states "/topic/?topic=The+Fundamental+Ideas+in+Chemistry". Usually it states "/topic/The+Fundamental+Ideas+in+Chemistry". Is there a way to remove the 'topic=' part from the url? – user2426062 Feb 27 '15 at 19:13
  • @user2426062 can you please update your question to include your view? Flask is not recognising that you have such a registration. – Martijn Pieters Feb 27 '15 at 19:21
  • Sorry I don't understand, would you like me to update my original question you mean? – user2426062 Feb 27 '15 at 19:37
  • @user2426062: I don't see the view function (at least the signature). Are there no other registrations? – Martijn Pieters Feb 27 '15 at 20:40
  • I've updated to show the entire view function of topic in case. What do you mean by registrations? – user2426062 Feb 27 '15 at 20:43
  • Your route is named "questions" not "topic", so you need to use `url_for('questions', topic='sometopic')` – FogleBird Feb 27 '15 at 21:03
  • @user2426062: Each `@app.route()` decorator registers another URL for a view. Your view endpoint is called `questions`, not `topic`; I adjusted my answer to fit your updated question. – Martijn Pieters Feb 27 '15 at 21:25
  • I tried your method and got a 'bad request', any suggestions? (I'll update this to my question after) – user2426062 Feb 27 '15 at 21:31
  • @user2426062: that'd be a *new* problem; you are probably trying to access request parameters that are not present or the wrong type, see [What is the cause of the Bad Request Error when submitting form in Flask application?](http://stackoverflow.com/q/14105452). Your original problem has been solved now though. – Martijn Pieters Feb 27 '15 at 21:52
  • @user2426062: If you have a new problem that you cannot solve with information found on Stack Overflow or elsewhere, you can ask a new question. The Stack Overflow format doesn't lend itself to progressive new questions. – Martijn Pieters Feb 27 '15 at 21:53