Flask - generate url with parameters in html - python

I am trying to find how I can pass a URL parameter (not request) into the url_for function, but I cant find it. In the following example, I need to pass the q_id through the form, as I do with incrRight. So, how can I have variables in url_for in this scenario ?
<form action="{{url_for('answer',q_id='5495eb77433f064294361ceb')}}" method="post">
<input type="text" name="incrRight" value="0">
<input type="submit"/>
</form>
This is what I have on my controller:
#app.route('/api/v1.0/question/<string:q_id>/answer', methods = ['POST'])
def answer(q_id):
incrRight = request.form.get('incrRight')
. . .
I need my html form to be able to communicate with the above function, by passing a q_id and the incrRight parameter.

You can add additional form parameters by adding more <input> tags. If the user of the form is not supposed to changed the items, use a <input type="hidden"> element:
<form action="{{ url_for('answer') }}" method="post">
<input type="text" name="incrRight" value="0" />
<input type="hidden" name="q_id" value="5495eb77433f064294361ceb" />
<input type="submit"/>
</form>
This does require that the answer() view can be invoked without the q_id parameter, of course:
#app.route('/api/v1.0/question/answer', methods=['POST'])
#app.route('/api/v1.0/question/<string:q_id>/answer', methods = ['POST'])
def answer(q_id=None):
if q_id is None:
q_id = request.form['q_id']
incrRight = request.form.get('incrRight')
Here a missing q_id parameter in the URL signals to the view that the browser included the question id in the POST body instead.
Another option is for you to write JavaScript code that'll adjust the form action parameter based on the q_id field in the form, but this then requires that your visitors have JavaScript enabled.

Related

How to pass the value to html input by add optional parameters to the link of the website to turn it into an API (flask)

I'm new to flask and I wonder how to pass the value to the HTML by adding optional parameters into the link
Example HTML:
<HTML>
<body>
<form method=post enctype=multipart/form-data>
<input type=text name=link>
<input type=submit value=Open>
</form>
</body>
</HTML>
Code I'm using to call the HTML above:
#app.route('/link', methods=['GET', 'POST'])
def open_link():
if request.method == "POST":
if 'link' != '':
text = request.form['link']
webbrowser.open(text)
return render_template("get_link.html")
Now, I want to add a parameter to the link to automatically pass the value for the input in, so that I can make it into an API
Example
http://192.168.5.107:8000/link/**add_para_here = hi**
Any suggestion? and only sorry for my bad English.Thank you
If I understand you correctly, you would like to use optional url parameters within your request. So that the url can be created in the following way.
http://127.0.0.1:8000/link?param0=value0&param1=1
In this case the form would look like this.
<form action="{{ url_for('link', param0='value1', param1=1) }}" method="post">
<input type="text" name="link">
<input type="submit" value="Open">
</form>
Within the endpoint, the parameters can be queried via request.args. Default values and an optional type conversion can also be specified here.
#app.route('/link', methods=['GET', 'POST'])
def open_link():
param0 = request.args.get('param0')
param1 = request.args.get('param1', 0, type=int)
if request.method == "POST":
if 'link' != '':
text = request.form['link']
# ...
return render_template("get_link.html")
Have fun implementing your project.

Django form input and action linking

How do you pass form inputs to a form action in Django? I tried this but it's not working
<form action="/search?search_term=q" method="get">
<input type="text" name="q">
<input type="submit" value="Search">
</form>
I'm assuming you're asking how to link an HTML form to a view function for processing. Note that in Django, we don't call them actions.
Here's the basic form and placeholder for the search results that you'd put in a Django template:
<form action="/search" method="get">
<input type="text" name="q">
<input type="submit" value="Search">
</form>
{% if search_results %}
Display search results here.
{% endif %}
If you type apple into the text field and then click the search button on this form it will make a GET request to /search?q=apple.
You will need to route the request via a URLconf to a view function to do the processing.
The entry in the URLconf may look like the following:
from django.conf.urls import url
from app import views
urlpatterns = [
# ...
url(r'^search/$', views.search),
# ...
]
views.search is the view function that does the processing. Here's a possible implementation:
from django.shortcuts import render
def search(request):
q = request.GET.get('q')
if q is None:
return render(request, 'app/search.html')
search_results = perform_search(q)
context = { 'search_results': search_results }
return render(request, 'app/search.html', context)
Where perform_search is a function you'd need to write to do the actual searching.
When you specify a method GET in form, then You don't need to append parameters explicitly in the URL. When the user submits the form your parameter will automatically append in the URL as key-value pairs.
Example
<form action="search" method="GET">
<input type="text" name="search_item1">
<input type="text" name="search_item2">
<input type="submit" value="Search">
</form>
When a user hit submit button then your parameter(serach_item1 and serach_item2) will append implicitly in action URL. where keys are input fields name attribute
Now your URL looks like
www.example.com/search?search_item1=<serach1>&search_item2=<serach2>
To pass GET arguments to the page you don't need to specify it in action attribute.
Just do follow:
<form method="GET" action="search/">
<input type="text" name="search_term" value="{{ request.GET.search_term }}">
<input type="submit" value="Search">
</form>
this will redirect you to the page http://yourdomain.com/search?search_term=search_text.
Please note I replaced input name attribute to rename GET argument to search_term. Also I added value attribute to display current search text to the input field.
shuboy2014 and neverwalkaloner are correct. But a fact they didn't tell you is that you'll pass empty values if you declare no values in that fields. For example:
<form method="GET" action="search/">
<input type="text" name="search_term">
<input type="submit" value="Search">
</form>
That would create an URL like http://yourdomain.com/search?search_term=, which could lead to unexpected errors in the View later. You either should do request.GET.get("search_term") to avoid exceptions or modify the submit function of your form to dinamically remove the names of those empty fields.

Can't pass a variable with Jinja in Flask

The form's action sends the input to a route named soldfor. I am trying to pass the variable ID into soldfor. When I hit the submit button I get this error:
TypeError: soldfor() takes exactly 1 argument (0 given)
Rendering of register_results.html:
return render_template('register_results.html', results=results, ID=ID)
register_results.html:
<form role="form" method="POST" action="{{ url_for('soldfor', ID={{ ID }}) }}">
<div class="input-group">
<input type="number" class="form-control" placeholder="Sold For" autocomplete="off" name="soldfor">
<span class="input-group-btn">
<button class="btn btn-default" name="soldfor" value="soldfor" type="submit">Sell!</button>
</span>
</div>
</form>
soldfor Route:
#app.route("/soldfor", methods=["POST"])
def soldfor(ID):
soldfor = request.form['soldfor']
print(soldfor)
g.db = connect_db()
g.db.execute("UPDATE yardsale SET SF = ? WHERE ID = ?", (soldfor, ID,))
g.db.commit()
g.db.close()
return redirect(url_for('index'))
You need to change this:
<form role="form" method="POST" action="{{ url_for('soldfor', ID={{ ID }}) }}">
to this:
<form role="form" method="POST" action="{{ url_for('soldfor', ID=ID) }}">
Also from the documentation:
When you define a route in Flask, you can specify parts of it that
will be converted into Python variables and passed to the view
function.
#app.route('/user/<username>')
def profile(username):
pass
Whatever is in the part of the URL labeled will get passed
to the view as the username argument. You can also specify a converter
to filter the variable before it’s passed to the view.
#app.route('/user/id/<int:user_id>')
def profile(user_id):
pass
Your error is being caused by the route expecting a parameter, but you are not passing one in. You should probably use something like that last example to accomplish what you're trying to do.
It's also sometimes desirable to pass a default value into the view function in case you need to use that URL without passing an ID. An example would look like this:
#app.route('/user/id/<int:user_id>')
def profile(user_id=0):
pass

Django: Template {% url %} tag, how to pass parameter from form

There is template:
<form action="{% url 'nfoapp.views.kinoscrap' <I WANT MOVIE_ID THERE> selectshort.id %}" method="post">
<input type="text" class="form-control" name="MOVIE_ID">
<button type="submit" class="btn btn-danger">Kinopoisk Search by ID</button>
</form>
There is my urls.py:
(r'^kinoscrap/(?P<kinoid>\d+)/(?P<shortid>\d+)/$', kinoscrap),
I want pass to kinoscrap two parameters - text field from form (MOVIE_ID) and 'selectshort.id' variable. The problem is that i can't put simple MOVIE_ID in first line of template, I got error. But when I try put instead MOVIE_ID other variable, for example selectshort.id, program work without error.
How I can trasmit text field value to view?
p.s I use bootstrap, if it has some importance.
You could have the form action empty, so to the same view, and then in the view redirect using the POST data from the form.
<form action="" method="post">
<input type="text" class="form-control" name="MOVIE_ID">
<button type="submit" class="btn btn-danger">Kinopoisk Search by ID</button>
</form>
And then in the view
def searchView(request):
if request.method == 'POST':
# get variables from form and redirect
else:
# do your normal rendering
(r'^kinoscrap/(?P<kinoid>\d+)/(?P<shortid>\d+)/$', kinoscrap),
Your urls.py accepts to integer values in the url (something like kinnoscrap/12/21), if you pass anything beside integers it'll throw an error. If you want to pass a text field you'll have to change the regular expression.
Try out your regexes at regex101 here to see if they'll work.

How to process two forms in one view?

I have two completely different forms in one template. How to process them in one view? How can I distinguish which of the forms was submitted? How can I use prefix to acomplish that? Or maybe it's better to write separate views?
regards
chriss
Personally, I'd use one view to handle each form's POST.
On the other hand, you could use a hidden input element that indicate which form was used
<form action="/blog/" method="POST">
{{ blog_form.as_p }}
<input type="hidden" name="form-type" value"blog-form" /> <!-- set type -->
<input type="submit" value="Submit" />
</form>
...
<form action="/blog/" method="POST">
{{ micro_form.as_p }}
<input type="hidden" name="form-type" value"micro-form" /> <!-- set type -->
<input type="submit" value="Submit" />
</form>
With a view like:
def blog(request):
if request.method == 'POST':
if request.POST['form-type'] == u"blog-form": # test the form type
form = BlogForm(request.POST)
...
else:
form = MicroForm(request.POST)
...
return render_to_response('blog.html', {
'blog_form': BlogForm(),
'micro_form': MicroForm(),
})
... but once again, I think one view per form (even if the view only accepts POSTs) is simpler than trying to do the above.
like ayaz said, you should give unique name to form submit button
<form action="." method="post">
......
<input type="submit" name="form1">
</form>
<form action="." method="post">
......
<input type="submit" name="form2">
</form>
#view
if "form1" in request.POST:
...
if "form2" in request.POST:
...
If the two forms are completely different, it will certainly not hurt to have them be handled by two different views. Otherwise, you may use the 'hidden input element' trick zacherates has touched upon. Or, you could always give each submit element a unique name, and differentiate in the view which form was submitted based on that.

Categories