Multiple buttons in html, same view, different values - python

I'm trying to have my html display a session.counter on an HTML page. The counter should increment by a random number, with 4 different options for the range at which it increments (based on buttons). So far, I have all their actions routing to the same view, but I'm not sure how to code the values into the view! Can I nest multiple if-checks into the view? If so, do I need to redirect immediately after each check, or can it be after the if-checks?
EDIT: I've tried adding hidden inputs to make my view more efficient. I'm still a novice, so if the more descriptive your feedback, the easier it will be for me to implement changes and understand why!
Here's the html:
<div id="goldCount">
<h2>Gold Count: {{ session.request.goldCount }}</h2>
</div>
<div id="goldNode">
<h2>Blood Lotus Master</h2>
<h5>(earns 50 to 200 gold coins)</h5>
<form action='/process_gold' method="post">
{% csrf_token %}
<input type="hidden" name="earn" value="reap">
<button type="submit" name="reap">収める - Reap</button>
</form>
</div>
<div id="goldNode">
<h2>Shadow Dance Troupe</h2>
<h5>(earns 35 to 50 gold coins)</h5>
<form action='/process_gold' method = "post">
{% csrf_token %}
<input type="hidden" name="earn" value="weave">
<button type = "submit" name = "weave">織る - Weave</button>
</form>
</div>
<div id="goldNode">
<h2>Necromancy</h2>
<h5>(earns -200 to 200 gold coins)</h5>
<form action='/process_gold' method="post">
{% csrf_token %}
<input type="hidden" name="earn" value="summon">
<button type = "submit" name="summon">召喚 - Summon</button>
</form>
</div>
<div id="goldNode">
<h2>Clan War!</h2>
<h5>(earns -2000 to 2000 gold coins)</h5>
<form action='/process_gold' method="post">
{% csrf_token %}
<input type="hidden" name="earn" value="summon">
<button type="submit" name="war">影の戦争 - Shadow War</button>
</form>
</div>
and here is the views.py file
def index(request):
if 'goldCount' not in request.session:
request.session['goldCount'] = 0
return render(request, 'index.html')
def process_gold(request):
reap = random.randint(50,200)
weave = random.randint(35,50)
summon = random.randint(-200,200)
war = random.randint(-2000,2000)
print(request.POST)
if request.POST['earn'] == 'reap':
request.session['goldCount'] += random.randint(50,200)
if request.POST['earn'] == 'weave':
request.session['goldCount'] += random.randint(35,50)
if request.POST['earn'] == 'summon':
request.session['goldCount'] += random.randint(-200,200)
if request.POST['earn'] == 'war':
request.session['goldCount'] += random.randint(-2000,2000)
return redirect('/')

If you want to send goldCount through to HTML you need to use a render_template rather than a redirect. Store the goldCount into session then just call {{request.session.goldCount}} in your HTML.
Also, the correct if statement would be:
if 'goldCount' not in request.session:
request.session['goldCount'] = 0

Related

Django I'm trying do perform a simple task, display on the page whatever was input in a textfield

All I want is the user to type in something in a single textfield and have the input displayed on the same page by the form. Please help!!!!
I tried so many solutions nothing seems to work and its such a simple task
please see my code:
views.py
def math_drills(request):
num1 = random.randint(0,100)
num2 = random.randint(0,100)
total = num2 + num1
if request.method == 'POST':
form = Addition(request.POST)
if form.is_valid():
u_i = request.POST['uans']
return redirect('math_drills_url')
return render(request,'math_drills.html',{
'num1':num1,
'num2':num2,
'total':total,
})
html
<div class="col-lg-12">
<script type="text/javascript">
</script>
<label class="" id="num1" name="">{{num1}}</label> +
<label class="" id="num2" name="">{{num2}}</label> =
<form action="" method="post">
{% csrf_token %}
<input id="your_name" type="text" name="uans" value="" id="" style="width:2%;">
<input type="submit" value="add">
</form>
</div>

How can I find the data which written with for loop in Flask

I'm trying to make a database project using with MYSQL and I'm new in Flask. In this project, the user should be able to increase and decrease the number of the products in the database. I print the items in my product table with for loop. The problem is I couldn't select the item which the user selected.
Html:
{% for mydata in data %}
<div class="items filterDiv {{ mydata[1] }}">
<img src="../static/foto/atayumurta.png" alt="">
<br><br>
<label for="item"> {{ mydata[3] }}</label>
<br><br>
<label class="Number">Number: <input class="numb" min="1" name="number" type="number"></label>
<br><br>
<input class="addbutton" type="submit" name="submit_button" value="Add">
<input class="removebutton" type="submit" name="removebutton" value="Remove">
</div>
{% endfor %}
Flask:
#app.route('/mainpage', methods=['POST','GET'])
def mainpage():
cursor.execute("SELECT * FROM product")
fetchdata = cursor.fetchall()
if request.method == 'POST':
if request.form['submit_button'] == 'Add':
number = request.form.get("number")
print(number)
return render_template('main.html', data=fetchdata)
else:
return render_template('main.html', data = fetchdata)
First, I wanted to see the number that the user has selected. So tried to print it but it prints null. As I said im new in flask, open for your suggestions.
Actually, the template contains a for loop for data.
In other words, the number field is not unique. So you need to modify the code. For example
{% for i in range(len(data)) %}
<div class="items filterDiv {{ data[i][1] }}">
<img src="../static/foto/atayumurta.png" alt="">
<br><br>
<label for="item"> {{ data[i][3] }}</label>
<br><br>
<label class="Number">Number: <input class="numb" min="1" name="number{{i}}" type="number"></label>
<br><br>
<input class="addbutton" type="submit" name="submit_button" value="Add">
<input class="removebutton" type="submit" name="removebutton" value="Remove">
</div>
{% endfor %}
Flask:
#app.route('/mainpage', methods=['POST','GET'])
def mainpage():
cursor.execute("SELECT * FROM product")
fetchdata = cursor.fetchall()
if request.method == 'POST':
if request.form['submit_button'] == 'Add':
number = request.form.get("number1")
print(number1)
return render_template('main.html', data=fetchdata)
else:
return render_template('main.html', data = fetchdata)

How to get dynamic html table entries in a form to flask?

I am trying to create a form with an embedded table that the user can dynamically add and remove table rows while entering content into the cell inputs.
HTML
<form id="myForm" action="{{ url_for('hello_world') }}" method="POST">
<div class="form-row text-left">
<div class="col-1 text-left">
<input type="checkbox" id="skills" name="skills" value="Yes">
</div>
<div class = "col-11 text-left">
<h2>TECHNICAL SKILLS</h2>
</div>
</div><!--form-row-->
<div class="form-row">
<table id="myTable" name="skillsTable">
<tr>
<th>Category</th>
<th>Entries</th>
</tr>
</table>
</div><!--form-row-->
<br>
<button type="button" onclick="addSkill()">Add Row</button>
<button type="button" onclick="deleteSkill()">Delete row</button>
<hr>
<input type="submit" value="Submit" onclick="submit()" />
</form>
As you can see in the screenshot [![screenshot of the user form][1]][1] the name attribute is correctly being appended to added cell.
The goal is to have a way to get the table values dynamically created by the user over to the flask template where they can be displayed.
Javascript
<script>
var c1=0;
var c2=0;
function addSkill() {
var table = document.getElementById("myTable");
var row = table.insertRow(-1);
var cell1 = row.insertCell(0);
var cell2 = row.insertCell(1);
cell1.innerHTML = "<input type='text' value=' ' name=cell1_"+c1.toString()+"> ";
cell2.innerHTML = "<input type='text' value=' ' name=cell2_"+c2.toString()+"> ";
c1++;
c2++;
}
function deleteSkill() {
document.getElementById("myTable").deleteRow(-1);
}
</script>
I have tried setting the name attribute for each newly created cell using a counter, but this still does not show up rendered in the flask template:
flask
#app.route('/hello_world', methods=['GET', 'POST'])
def hello_world():
if request.method == 'POST':
result = {}
try:
skills = request.form['skills']
result['skills'] = skills
result['value'] = request.form['cell1_1']
except:
pass
return render_template("result.html",result = result)
result.html
{% if result.skills %}
<p>{{ result.value }}</p>
{% endif %}
In this example, I would expect to see "Language" show up on rendered after submitting the form if the checkbox is selected.
How can I refer to the table in the form from flask and loop through the <input> elements if they are dynamically created? Thx
[1]: https://i.stack.imgur.com/samhG.png
result.html
{% if result.skills %}
{% set skillsTable = result.skillsTable %}
<h2>TECHNICAL SKILLS</h2>
<table>
{% for skill in skillsTable %}
{% if loop.index|int % 2 == 0 %}
<tr><td>{{ skillsTable.pop(0) }}:</td><td>{{ skillsTable.pop(0) }}</td></tr>
{% else %}
<tr><td>{{ skillsTable.pop(0) }}:</td><td>{{ skillsTable.pop(0) }}</td></tr>
{% endif %}
{% endfor %}
{% endif %}
flask
#app.route('/hello_world', methods=['GET', 'POST'])
def hello_world():
if request.method == 'POST':
result = {}
try:
skills = request.form['skills']
result['skills'] = skills
result['skillsTable'] = []
form = request.form
for key, value in form.items():
if key.startswith("cell"):
result['skillsTable'].append(value)
except:
pass
return render_template("result.html",result = result)

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)

Flask-WTForms: dynamically create name and id attributes

My form allows the user to enter a specific number of names for a specific number of basketball teams. These numbers are constantly updated so I need to create a dynamic form.
Let's say I have the following Flask view:
#app.route('/dynamic', methods=['GET', 'POST'])
def dynamic():
teams = ['Warriors', 'Cavs']
name_count = 2
return render_template('dynamic.html', teams=teams, name_count=name_count)
And the following form in the HTML template dynamic.html:
<form method='POST' action='/dynamic'>
{% for team_index in range(teams | count) %}
{% for name_index in range(name_count) %}
<input type="text"
class="form-control"
id="team{{ team_index }}_name{{ name_index }}"
name="team{{ team_index }}_name{{ name_index }}">
{% endfor %}
{% endfor %}
<form>
Which yields the following form:
<form method='POST' action='/dynamic'>
<input type="text" class="form-control" id="team0_name0" name="team0_name0">
<input type="text" class="form-control" id="team0_name1" name="team0_name1">
<input type="text" class="form-control" id="team1_name0" name="team1_name0">
<input type="text" class="form-control" id="team1_name1" name="team1_name1">
<form>
I love the Flask-WTF library so I'm wondering how I can use that (or simply wtforms) to render this form. I'm not sure this is even possible because wtforms requires a hardcoded field name for every input.
Figured this out. I need to use the WTForms Fieldlist and FormField enclosures.
class PlayerForm(FlaskForm):
player = Fieldlist(StringField('Player'))
class TeamForm(FlaskForm):
team = Fieldlist(FormField(PlayerForm))
#app.route('/dynamic', methods=['GET', 'POST'])
def dynamic():
teams = ['Warriors', 'Cavs']
name_count = 2
# Build dictionary to prepopulate form
prepop_data = {'team': [{'player': ['' for p in range(name_count)]} for team in teams]}
# Initialize form
form = TeamForm(data=prepop_data)
return render_template('dynamic.html', form=form)
And unpacking via jinja2 (id and name attributes on first field = team-0-player-0):
<form method="POST" action="/dynamic">
{{ form.csrf_token }}
{% for team in form.team %}
{{ team.csrf_token }}
{% for player in team.player %}
{{ render_field(player) }}
{% endfor %}
{% endfor %}
</form>

Categories

Resources