Unable to get value selected in python from a dropdown using Flask - python

This question could be a duplicate but I have checked all the answers of such related questions and I haven't been able to solve it.
I am trying to get the value from a dropdown menu which consists of numbers. Then I want to compare the numbers with a value and display a text based on the comparison.
Eg
if value_selected_from_dropdown >3
display text
I am unable to get the text to display or even print the value of the option selected.
Here is the python file, web_plants.py
from flask import Flask, render_template,request, redirect, url_for
app = Flask(__name__)
def template(title = "HELLO!", text = ""):
templateDate = {
'text' : text
}
return templateDate
#app.route("/threshold", methods=['POST'])
def threshold():
tvalue= (request.form.get['tvalue']) #get value from dropdown
msg= ""
if tvalue>3:
msg= "rating above 3"
templateData = template(text = msg) #display text using template()
#templateData = template(text = tvalue) #tried to print the value selected
return render_template('index.html', **templateData)
if __name__ == "__main__":
app.run(host='0.0.0.0', port=80, debug=True)
index.html:
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" type="text/css" href="{{ url_for('static',filename='style.css')}}" />
</head>
<body>
<h2> {{ text }} </h2>
<form action= "{{ url_for('threshold') }}" method="post>"
<p>
<select name= 'tvalue'>
<option value="10">10</option>
<option value="11">11</option>
<option value="15">15</option>
<option value="2">2</option>
<option value="1">1</option>
</select>
</p>
</form>
</body>
</html>

There are several ways to achieve this. Either you can give logic to the template itself or you can add the logic in the function threshold.
index.html
<h2> {{text}} </h2>
<form action= "{{ url_for('threshold') }}" method="POST">
<select name= 'tvalue'>
{% for tvalue in tvalues %}
{% if selected_tvalue == tvalue %}
<option value="{{ tvalue }}" selected='selected'>{{ tvalue }}</option>
{% else %}
<option value="{{ tvalue }}" >{{ tvalue }}</option>
{% endif %}
{% endfor %}
</select>
<input type="submit" value="Submit" />
</form>
OR,
{% if selected_tvalue > 3 %}
<h2> Selected value is greater than 3 </h2>
{% else %}
<h2> Selected value is less than or equal to 3 </h2>
{% endif %}
<form action= "{{ url_for('threshold') }}" method="POST">
<select name= 'tvalue'>
{% for tvalue in tvalues %}
{% if selected_tvalue == tvalue %}
<option value="{{ tvalue }}" selected='selected'>{{ tvalue }}</option>
{% else %}
<option value="{{ tvalue }}" >{{ tvalue }}</option>
{% endif %}
{% endfor %}
</select>
<input type="submit" value="Submit" />
</form>
server.py
def template(title = "HELLO!", text = ""):
templateDate = {
'text' : text,
'tvalues' : getTValues(),
'selected_tvalue' : -1
}
return templateDate
def getTValues():
return (10, 11, 15, 2, 1)
#app.route("/threshold", methods=['POST', 'GET'])
def threshold():
tvalue= -1 #default value
msg = ''
if request.method == "POST":
tvalue = int(request.form['tvalue'])
if tvalue> 3:
msg= "rating above 3"
#generating template data
templateData = template(text = msg)
templateData['selected_tvalue'] = tvalue
return render_template('index.html', **templateData)
Then access your form at path /threshold. I hope it helps.

In your html after your drop down block you may need something like
<input type="submit">
which will trigger the submit. I am not sure, selecting a value alone triggers the form submit.
By the way where are you rendering your page initially ? I would have something like:
#app.route('/')
#app.route('/index')
def index():
return render_template('index.html')
in the python code. There to get the value, I would try
tvalue= request.args.get('tvalue')
Well not 'form' but 'args', and normal brackets instead of squared ones. Finally the function where you are going to handle that 'templateData' might be missing too.
last note:
you might need GET method too:
#app.route("/threshold", methods=['GET', 'POST'])

Related

How to display Selected option value Selected in option tag in Django Template File?

I want to keep user selected option active from the long SELECT OPTION dropdown list what they choose from SELECT OPTION. active mean display selected value. Like by default in select options it shows Spanish To English(first one) but if user selects French To English I want to keep selected this one
This is my HTML form in template file.
<form action="" method="post">
{% csrf_token %}
<div class="d-flex form-inputs">
<select class="form-select" aria-label=".form-select-lg" name="lang_txt">
<option value="span_to_eng">Spanish To English</option>
<option value="eng_to_span">English To Spanish</option>
<option value="french_to_eng">French To English</option>
</select>
<input name="txt" class="form-control p-3" type="text" placeholder="Search...">
<img src="/static/assets/image/search.png" alt="">
</div>
</form>
This is views function
def lang_convert_view(request):
if request.method == "POST" and 'txt' in request.POST:
txt = request.POST.get('txt')
selected_lang = request.POST.get('lang_txt')
data = custom_function_name(txt)
context = {'data': data}
else:
context = {}
return render(request, 'index.html', context)
Views:
def lang_convert_view(request):
if request.method == "POST" and 'txt' in request.POST:
txt = request.POST.get('txt')
selected_lang = request.POST.get('lang_txt')
data = custom_function_name(txt)
context = {'data': data}
else:
data = Model.objects.get(id='your query')
context = {'data': data}
return render(request, 'index.html', context)
Template:
<form action="" method="post">
{% csrf_token %}
<div class="d-flex form-inputs">
<select class="form-select" aria-label=".form-select-lg" name="lang_txt">
<option value="span_to_eng" {% if data.selected_lang == 'span_to_eng' %}selected{% endif %}>Spanish To English</option>
<option value="eng_to_span" {% if data.selected_lang == 'eng_to_span' %}selected{% endif %}>English To Spanish</option>
<option value="french_to_eng" {% if data.selected_lang == 'french_to_eng' %}selected{% endif %}>French To English</option>
</select>
<input name="txt" class="form-control p-3" type="text" placeholder="Search...">
<img src="/static/assets/image/search.png" alt="">
</div>
</form>

How to load dropdowns and pass values using flask

using Python and Flask I have this Flask file which should take a couple of inputs from the user and pass those to a python script to be used. I can get 2 boxes that will accept numbers as inputs and those work just fine using the code below.
from flask import Flask, request, render_template
import os
import csv
import fileinput
import codecs
import re
import pandas as pd
import os
from pandas.core.dtypes.missing import notnull
from races import calculate_mode
from races import do_calculation
#import races
app = Flask(__name__)
app.config["DEBUG"] = True
inputs = []
#app.route("/testing", methods=["GET", "POST"])
def testing():
errors = ""
number1 = None
number2 = None
colours = ['Red', 'Blue', 'Black', 'Orange']
if request.method == "POST":
try:
number1 = float(request.form["number1"])
except:
errors += "<p>{!r} is not a number.</p>\n".format(request.form["number1"])
try:
number2 = float(request.form["number2"])
except:
errors += "<p>{!r} is not a number.</p>\n".format(request.form["number2"])
if number1 is not None and number2 is not None:
result = do_calculation(number1, number2)
return '''
<html>
<body>
<p>The result is {result}</p>
<p>Click here to calculate again
</body>
</html>
'''.format(result=result)
return '''
<html>
<body>
{errors}
<p>Enter your numbers:</p>
<form method="post" action=".">
<p><input name="number1" /></p>
<p><input name="number2" /></p>
<p><input type="submit" value="Do calculation" /></p>
</form>
</body>
</html>
'''.format(errors=errors)
if __name__ == "__main__":
app.run(debug=True)
But for this application it really needs to be drop down boxes. I have gotten a dropdown box to load using something like this:
#app.route("/dropdown", methods=["GET", "POST"])
def select():
colours = ['Red', 'Blue', 'Black', 'Orange']
return render_template('select.html', colours=colours)
However I don't know how to pass arguments from a newly loaded page and the python file. So instead I'm trying to load the html in the same file by replacing the second 'return' with the code below (which is basically the same as the file that is loaded with select.html) but can't get the dropdown to work (error is KeyError: '% for colour in colours')
return '''
<html>
<form>
<select name="colour" method="POST" action="/">
<option value="{{colours[0]}}" selected>{{colours[0]}}</option>
{% for colour in colours[1:] %}
<option value="{{colour}}">{{colour}}</option>
{% endfor %}
</select>
<p><input type="submit" value="Do calculation" /></p>
</form>
</html>
'''.format(errors=errors)
Does anyone know why it won't work, or have a better idea of how to do this?
Your problem is that you use .format() to format HTML and format treats all { } as places for variables - even {%...%} - and it doesn't know what means this {% ... %}.
You should use render_template_string() instead of format()
if number1 is not None and number2 is not None:
result = do_calculation(number1, number2)
html = '''
<html>
<body>
<p>The result is {{ result }}</p>
<p>Click here to calculate again
</body>
</html>
'''
return render_template_string(html, result=result)
html = '''
<html>
<form>
{{ errors }}
<select name="colour" method="POST" action="/">
<option value="{{ colours[0] }}" selected>{{colours[0]}}</option>
{% for colour in colours[1:] %}
<option value="{{ colour }}">{{ colour }}</option>
{% endfor %}
</select>
<p><input type="submit" value="Do calculation" /></p>
</form>
</html>'''
return render_template_string(html, colours=colours, errors=errors)
or
if number1 is not None and number2 is not None:
result = do_calculation(number1, number2)
return render_template_string('''
<html>
<body>
<p>The result is {{ result }}</p>
<p>Click here to calculate again
</body>
</html>
''', result=result)
return render_template_string('''
<html>
<form>
{{ errors }}
<select name="colour" method="POST" action="/">
<option value="{{ colours[0] }}" selected>{{colours[0]}}</option>
{% for colour in colours[1:] %}
<option value="{{ colour }}">{{ colour }}</option>
{% endfor %}
</select>
<p><input type="submit" value="Do calculation" /></p>
</form>
</html>''', colours=colours, errors=errors)

Python/Flask, request ID from dropdownlist populated options with SQLite

I'm trying to get the IDs selected with a dropdown and add it to my table without the use of JSON but I keep getting the same error :
werkzeug.exceptions.HTTPException.wrap..newcls: 400 Bad
Request: KeyError: 'nomFabri'
I have three tables:
https://i.stack.imgur.com/W7v7x.png
(can't post image yet, sadly)
Thought it would work fine and tried to mess around with my columns, without much success. Most of what I got from my researchs are to use JSON isn't there a workaround without using it ?
Here the code
#bp.route('/Appareil', methods=['GET', 'POST'])
def Appareil():
db = get_db()
materielTypes = db.execute(
'SELECT * FROM t_type'
).fetchall()
fabriquants = db.execute(
'SELECT * FROM t_fabriquant'
).fetchall()
return render_template('materiel/appareil.html',
materielTypes=materielTypes, fabriquants=fabriquants)
#bp.route('/AddAppareil', methods=['GET', 'POST'])
def AddAppareil():
if request.method == 'POST':
nomModele = request.form['nomModele']
numeroProduit = request.form['numeroProduit']
nomFabri = request.form['nomFabri']
matType = request.form['matType']
error = None
if not nomModele:
error = 'Faux.'
if error is not None:
flash(error)
else:
db = get_db()
db.execute(
'INSERT INTO t_appareil (nomModele, numeroProduit, nomFabri, mattype)'
' VALUES (?, ?, ?, ?)',
(nomModele, numeroProduit, nomFabri, matType,)
)
db.commit()
return redirect(url_for('materiel.appareil'))
return render_template('materiel/appareil.html')
And here the form
{% extends 'base.html' %}
{% block header %}
<h1>{% block title %}nouvel appareil{% endblock %}</h1>
{% endblock %}
{% block content %}
<form method="post" class="insertdata" action="/AddAppareil">
<select>
{% for materielType in materielTypes %}
<option name="matType" id="matType" value="{{ request.form['id_type'] }}">{{ materielType['materielType'] }}</option>
{% endfor %}
</select>
<select>
{% for fabriquant in fabriquants %}
<option name="nomFabri" id="nomFabri" value="{{ request.form['id_fabriquant']] }}">{{ fabriquant['nomFabr'] }}</option>
{% endfor %}
</select>
<input type="text" name="nomModele" id="nomModele" placeholder="nom du Modele" value="{{ request.form['nomModele'] }}" required>
<input type="text" name="numeroProduit" id="numeroProduit" placeholder="Numéro de série" value="{{ request.form['numeroProduit'] }}" required>
<input type="submit" value="Save">
</form>
{% endblock %}
Thanks for any help provided :)
You need to add name value to select <select name='mateType'>...</select>, <select name='nomFabri'>...</select>. Another problem, you need to remove value="{{ request.form['nomModele'] }}" from select and input fields.
Your python code will be similar to this:
#bp.route('/AddAppareil', methods=['GET', 'POST'])
def AddAppareil():
nomModele = ''
numeroProduit= ''
nomFabri= ''
matType= ''
if request.method == 'POST':
nomModele = request.form['nomModele']
numeroProduit = request.form['numeroProduit']
nomFabri = request.form['nomFabri']
matType = request.form['matType']
error = None
if not nomModele:
error = 'Faux.'
if error is not None:
flash(error)
else:
db = get_db()
db.execute(
'INSERT INTO t_appareil (nomModele, numeroProduit, nomFabri, mattype)'
' VALUES (?, ?, ?, ?)',
(nomModele, numeroProduit, nomFabri, matType,))
db.commit()
return redirect(url_for('materiel.appareil'))
db = get_db()
materielTypes = db.execute(
'SELECT * FROM t_type'
).fetchall()
fabriquants = db.execute(
'SELECT * FROM t_fabriquant'
).fetchall()
return render_template('materiel/appareil.html',
nomModele = nomModele, numeroProduit=numeroProduit,
nomFabri=nomFabri, matType=matType,
materielTypes=materielTypes,fabriquants = fabriquants)
And the appareil.html file will be similar to this:
{% extends 'base.html' %}
{% block header %}
<h1>{% block title %}nouvel appareil{% endblock %}</h1>
{% endblock %}
{% block content %}
<form method="post" class="insertdata" action="/AddAppareil">
<select name='matType'>
{% for materielType in materielTypes %}
<option value="{{ materielType['id_type'] }}"
{% if matType == materielType['id_type'] %} selected {% endfor %} >
{{ materielType['materielType'] }}
</option>
{% endfor %}
</select>
<select name="nomFabri" id="nomFabri">
{% for fabriquant in fabriquants %}
<option value="{{ fabriquant['id_fabriquant'] }}"
{% if nomFabri == fabriquant['id_fabriquant'] %} selected {% endfor %}>
{{ fabriquant['nomFabr'] }}
</option>
{% endfor %}
</select>
<input type="text" name="nomModele" id="nomModele" placeholder="nom du Modele"
value="{{ nomModele }}" required>
<input type="text" name="numeroProduit" id="numeroProduit"
placeholder="Numéro de série" value="{{ numeroProduit }}" required>
<input type="submit" value="Save">
</form>
{% endblock %}
And you need to add some default values for the form fields:
#bp.route('/Appareil', methods=['GET', 'POST'])
def Appareil():
#...
return render_template('materiel/appareil.html',
materielTypes=materielTypes, fabriquants=fabriquants
nomModele = '',
numeroProduit= '',
nomFabri='',
matType='')

Django - Taking value from POST request

I have a list of zones, identified by id (integer).
How can I get the zone that generated the post request?
manual.html
{% if zone_list %}
<ul>
{% for z in zone_list %}
<b><p>{{z.name}}</p></b>
<form action="" method="post">
{% csrf_token %}
<input type="submit" name="{{z.id}}" value="ON"/>
<input type="submit" name="{{z.id}}" value="OFF"/><br>
<br>
<label>Tiempo</label>:
<input type="integerfield" name="Tiempo">
<input type="submit" name="{{z.id}}" value="Start">
</form>
{% endfor %}
</ul>
{% endif %}
In the views.py I have to change the 1 for something that dynamically represents the zone
views.py
def manual(request):
if request.POST.has_key('1'):
z = Zone.objects.get(id = 1)
keyword = request.POST.get("1","")
if keyword == "ON":
#do something
if keyword == "OFF":
#do something
if keyword == "Start":
#do something
zone_list = Zone.objects.all()
context = {'zone_list':zone_list}
return render(request, 'irrigation_controller/manual.html', context)
I solved the problem. As themanatuf said, I used a hidden input field with the zone_id.
manual.html
{% if zone_list %}
{% for z in zone_list %}
<b><p>{{z.name}}</p></b>
<form action="" method="post">
{% csrf_token %}
<input type="hidden" name="zone_id" value="{{z.id}}">
<input type="submit" name="order" value="ON"/>
<input type="submit" name="order" value="OFF"/><br>
<br>
<label>Tiempo</label>:
<input type="integerfield" name="Tiempo">
<input type="submit" name="order" value="Start">
</form>
{% endfor %}
{% endif %}
And in the view I read the zone_id and the order.
views.py
def manual(request):
if request.POST.has_key('zone_id'):
z = Zone.objects.get(id = request.POST.get("zone_id",""))
keyword = request.POST.get("order","")
if keyword == "ON":
z.irrigation_on()
if keyword == "OFF":
z.irrigation_off()
if keyword == "Start":
tiempo = request.POST['Tiempo']
tiempo = float(tiempo)
irrigation_time.delay(z.id, tiempo)
zone_list = Zone.objects.all()
context = {'zone_list':zone_list}
return render(request, 'irrigation_controller/manual.html', context)

Get POST from multiple dropdowns in one form

Have a form where user can change name on attribut Name and change which attribut a is connected to (attribut b).
Template:
"<form id="form1" name="form1" method="post" action="/define_a/{{c.id}}/edit/">
{% csrf_token %}
{% endblock %}
{% block buttons %}
<p><input type="submit" value="Save" /> Cancel
</p>
{% endblock %}
{% block a_rows %}
{% for a, a_form in a_list %}
<tr><td><img class="icon" src="{{images_dir}}/delete-icon.png"
onclick="javascript: return confirmDelete_name('Are you sure?
This will delete the stuff and all associated information.
The removal happens immediately and cannot be undone.', '{{a.id}}', 'delete');" />
</td><td>{{a_form.name}}</td>
<td>
<select name= "test">
<option value = "Null">None</option>
<option value = "{{a_form.id}}" selected>{{a.b}}</option>
{% for a, a_form in a_list %}
<option value = "{{a_form.id}}">{{a.name}}</option>
{% endfor %}"
View:
Checking that it is a post and that it is valid.
post = [myForm(request.POST, instance = test) for a in a's];
for p in post :
if not new_t.b == p:
if p == 'None':
new_t.b = None;
else:
new_t.b = p;
But i can't get all the values from the dropdown in the post.
I get all a.name in but only one value from the dropdown, sometimes I don't get any value at all.
Any ideas?

Categories

Resources