How to make a checkbox checked in Jinja2 - python

I am learning flask programming and cannot figure out how to make a radio input checked, here is the html template I am using:
<form method = "POST" action="/proxy_settings">
<input type="radio" name="proxy_mode" value = '0'>Auto
<br>
<input type="radio" name="proxy_mode" value = '1'>Manual
<br>
<br>
<section>
<table border="1">
<tr>
<td>Description</td>
<td>delay</td>
<td>select</td>
</tr>
{% for node_name, node_delay in node_list.items() %}
<tr>
<td>{{node_name}}</td>
<td>{{node_delay}}</td>
<td><input type="radio" name="proxy_node"></td>
</tr>
{% endfor %}
</table>
</section>
<br>
<section>
<button type="submit">CONFIRM</button>
</section>
</form>
I am rendering this template in flask like this:
return render_template("base.html", node_number = ret["node_number"], proxy_mode = ret1["proxy_mode"], proxy_node = ret2["proxy_node"], node_list=ret3)
My question is:
How to make proxy_mode radio input checked according to the value of variable proxy_mode?
How to make proxy_node radio input checked according to the value of variable proxy_node? For example, if proxy_node equals to 2, then the radio input in row 2 of the table will be checked.
How to assign a value attribute dynamically to the radio input proxy_node?
I have tried the following method for question 1 but it doesn't work.
<input type="radio" name="proxy_mode" value = '0' {% if proxy_mode == 0 %} checked=true {% endif %}>Auto
<br>
<input type="radio" name="proxy_mode" value = '1' {% if proxy_mode == 1 %} checked=true {% endif %}>Manual
Thanks in advance!

This should be the easiest way.
<input type="radio" name="proxy_mode" value="0" {{ "checked" if proxy_mode == 0 }}>Auto
<br>
<input type="radio" name="proxy_mode" value="1" {{ "checked" if proxy_mode == 1 }}>Manual

After reading through Jinja2 Template Designer Documentation and another stackoverflow question I was able to come up with a solution for my problems:
Use Jinja statements to control whole html tag instead of a property of this tag. So, the form looks like this after modification:
<form method = "POST" action="/proxy_settings">
{% if proxy_mode == '0' %}
<input type="radio" name="proxy_mode" value = '0' checked=true>Auto
{% else %}
<input type="radio" name="proxy_mode" value = '0'>Auto
{% endif %}
<br>
{% if proxy_mode == '1' %}
<input type="radio" name="proxy_mode" value = '1' checked=true>Manual
{% else %}
<input type="radio" name="proxy_mode" value = '1'>Manual
{% endif %}
<br>
<br>
<section>
<table border="1">
<tr>
<td>Description</td>
<td>delay</td>
<td>select</td>
</tr>
{% for node_name, node_delay in node_list.items() %}
<tr>
<td>{{node_name}}</td>
<td>{{node_delay}}</td>
{% if loop.index0 == proxy_node|int %}
<td><input type="radio" name="proxy_node" value={{loop.index0}} checked=true></td>
{% else %}
<td><input type="radio" name="proxy_node" value={{loop.index0}}></td>
{% endif %}
</tr>
{% endfor %}
</table>
</section>
<br>
<section>
<button type="submit">CONFIRM</button>
</section>
</form>
Hope this answer will help whoever viewed this question. Thanks!

Related

How to attach different indices to an html element with jinja?

I am creating a simple html questionnaire document, as a base template I am using the following jinja code:
from jinja2 import Template
title = ['1 title', '2 title']
message = ['1 message', '2 message']
template = Template(
"""
{% macro create_block(title, message) %}
<h1> {{title}} </h1>
<h3>question?</h3>
<input type="radio" value="val1" name="question1_{{ i }}">option A</input>
<input type="radio" value="val2" name="question1_{{ i }}">option B</input>
<h3>question 2?</h3>
<input type="radio" value="one" name="question1_{{ i }}">a</input>
<input type="radio" value="two" name="question1_{{ i }}">b</input>
<input type="radio" value="three" name="question1_{{ i }}">c</input>
{% endmacro %}
{% for title, message in list %}
{{ create_block(title, message) }}
{% endfor %}
""")
print_html(template.render(list=zip(title, message)))
The above template creates questions sets for the number of elements in title and message lists. For example, for two elements in title, the above code will generate two different questionnaire sets. However, to produce a valid html document I would like to vary the {{i}} parameter in name="question1_{{ i }}. For the above template, the expected output looks like this:
<h1>
1 title
</h1>
<h3>
question?
</h3>
<input name="question1_1" type="radio" value="val1"/>
option A
<input name="question1_1" type="radio" value="val2"/>
option B
<h3>
question 2?
</h3>
<input name="question1_2" type="radio" value="one"/>
a
<input name="question1_2" type="radio" value="two"/>
b
<input name="question1_2" type="radio" value="three"/>
c
<h1>
2 title
</h1>
<h3>
question?
</h3>
<input name="question2_1" type="radio" value="val1"/>
option A
<input name="question2_1" type="radio" value="val2"/>
option B
<h3>
question 2?
</h3>
<input name="question2_2" type="radio" value="one"/>
a
<input name="question2_2" type="radio" value="two"/>
b
<input name="question2_2" type="radio" value="three"/>
c
In Jinja, what is the correct way to get the above output with the indices of the checkboxes names varying?
You would pass the index as an argument just like you did for the others.
from jinja2 import Template
title = ['1 title', '2 title']
message = ['1 message', '2 message']
indices = list(range(len(title)))
template = Template(
"""
{% macro create_block(title, message, i) %}
<h1> {{title}} </h1>
<h3>question?</h3>
<input type="radio" value="val1" name="question1_{{ i }}">option A</input>
<input type="radio" value="val2" name="question1_{{ i }}">option B</input>
<h3>question 2?</h3>
<input type="radio" value="one" name="question1_{{ i }}">a</input>
<input type="radio" value="two" name="question1_{{ i }}">b</input>
<input type="radio" value="three" name="question1_{{ i }}">c</input>
{% endmacro %}
{% for title, message, i in list %}
{{ create_block(title, message, i) }}
{% endfor %}
""")
print_html(template.render(list=zip(title, message, indices)))

Why not take the data from the inserted in flask?

I am trying to insert several data in one table to another but it is not taking the data from the HTML, I have tried several ways, I also tried to take the number as a variable and insert it directly but it did not work.
This is what I am trying to do, that 2 tables bring me a value and insert them in a table called quantity, which has 2 ids and only 3 fields, where is the id, the count and the id of the product but when I try Insert the data, the page only reloads.
Python
if request.method == 'POST':
try:
dcont = request.form['dcont']
ids = request.form['ids']
cn = request.form['cn']
with sql.connect("DRIVER={SQL Server}; SERVER=AUS_COMPUTO02\SQLEXPRESS; DATABASE=WEBSERVICE; Trusted_Connection = yes;") as con:
cur = con.cursor()
cur = con.execute("INSERT INTO dbo.DETALLECONTEO VALUES (?,?,?)", (dcont,ids,cn))
cur.commit()
msg = "Successfully added"
print(cur)
print(dcont,ids,cn)
except:
con.rollback()
msg = "error inserte la operacion nuevamente"
finally:
# con.close()
return render_template ('result.html')
return render_template('new.html', prov=prov, cnt=cnt, ind=ind )
HTML
<div class="jumbotron">
<div class="form-group">
<form class="form-inline my-2 my-lg-0" action="{{ url_for('new') }}" class="form-control" class="w-auto p-3">
<select name='prove' class="form-control mr-sm-2" aria-label="Search" >
<option value="0"> Selecione su Proveedor </option>
<br action="{{ url_for('new') }}" method='POST'>
{% for p in prov %}
<option value="{{ p.ID }}" > {{ p.DESCRIPCION }} </option>
{% endfor %}
</select>
<button class="btn btn-outline-success my-2 my-sm-0" type="submit" >Seclet</button>
</form>
</div>
<div class="form-group">
<form class="form-inline my-lg-0" action="{{ url_for('adt') }}" method='POST'>
<table class="table" class="form-control">
<thead>
<tr>
<th scope="col">Codigo</th>
<th scope="col">Descipcion</th>
<th acope="col">Cantidad</th>
</tr>
</thead>
<tbody>
{% for c in cnt %}
<tr>
<td >{{ c.codigo }}</td>
<td>{{ c.descripcion }}</td>
<td > <input name='cn' id='cn' type="number" class="form-control"></td>
<td><select name='dcont' id='dcont'>
{% for i in ind %}
<option value=" {{i.Conteo}}"> {{i.Conteo}} </option>
{% endfor %}
</select>
</td>
<td> <select name='ids' id='ids'>
<option value="{{c.id}}"> {{c.id}} </option>
</select>
</td>
{% endfor %}
</tr>
</tbody>
</table>
</tbody>
</table>
<input class="btn btn-outline-success my-2 my-sm-0" type="submit" ><br>
</form>
</div>
</div>
Two main areas to focus on-- first your form hasn't been told to 'POST' the data-- go it's going to send it via the default 'GET' mode, changing your form code, by adding method="post" will resolve that issue.
<form class="form-inline my-2 my-lg-0" method="post" action="{{ url_for('new') }}" class="form-control" class="w-auto p-3">
So now your form data will get POST'ed-- and so will trigger the if request.method == 'POST': logic.
Your next issue is your data is coming in as the same named element-- e.g. if you submitted three entries, your ids element would post:
ids=3
ids=2
ids=6
So we need to use the request.form.getlist('ids') to get that data, so you end up with a list of entries for the form elements:
all_ids = request.form.getlist('ids')
all_cn = request.form.getlist('cn')
all_dcont = request.form.getlist('dcont')
Now if we looked at that data that might be submitted:
>>> print(all_ids)
['3','2','6']
>>> print(all_dcont)
['A','B','C']
>>> print(all_cn)
['X','Y','Z']
But we need to handle them as rows-- to insert into our database, so we can zip them together to make 'rows' of the data:
rows = zip(all_ids, all_dcont, all_cn)
So now we have:
>>> print(rows)
['3','A','X'], ['2','B','Y'], ['6','C','Z']
Which we can iterate through (theres a number of ways to do this, we'll keep it simple) to create out SQL statements to execute:
for entry in rows:
query_ids = entry[0]
query_dcont = entry[1]
query_cn = entry[2]
...
cur = con.execute("INSERT INTO dbo.DETALLECONTEO VALUES (?,?,?)", (query_dcont,query_ids,query_cn))
...

Django search form for filtering

I am currently doing a search using forms
This is my views.py
class HomeView(generic.ListView):
model = Consultant
template_name = 'sogeti/home.html'
def get_queryset(self):
query = self.request.GET.get('q')
if query:
return Consultant.objects.filter(
Q(first_name__icontains=query) |
Q(last_name__icontains=query) |
Q(group__title_techGroup__contains=query) |
Q(practices__title_practice__contains=query)
)
else:
return Consultant.objects.all()
and this is my home.html
<form action="" method="get" class="form-inline">
<input type="text" name="q" placeholder="Enter Keyword" value="{{ request.GET.q }}" class="form-control">
<select name="filter" class="form-control">
<option value="all">All</option>
<option value="people">People</option>
<option value="certification">Certification</option>
<option value="skillset">Skillset</option>
</select>
<input type="submit" value="Search" class="btn btn-default">
</form>
<ol style="padding-left: 15px">
{% for consultant in object_list %}
<li>
{{ consultant.first_name }}, {{ consultant.last_name }} </br>
Technology Group: {{ consultant.group }} </br>
Primary Practice: {{ consultant.practices }}
<hr style="margin-left: 0">
</li>
{% endfor %}
</ol>
My first problem is that when it tries to search something (Eg: bla) that is not in my database, it returns a blank screen. Nothing at all. Tried searching but could not get any answers.
My second problem is how am I able to specify my search using HTML select and options to filter. As you can see from my home.html I have the tag with option value but no idea how to utilize it for Django.
Thank you so much for your help! Really appriciate it.
About first issue, you actually can double check the object_list before iterate over it, e.g:
{% if object_list %}
<ul>
{% for item in object_list %}
<p>{{item.value}}</p>
{% endfor %}
</ul>
{% else %}
<p>Empty!</p>
{% endif %}
If you're unable to search, then double check your query by using some tools like django-debug-toolbar to take a look at the queries.
About the second question, I recommend you to use Django Form instead, like so:
Create forms.py:
from django.forms import Form, ChoiceField, CharField
class FilterForm(Form):
FILTER_CHOICES = (
('all', 'All'),
('people', 'People'),
('certification', 'Certification'),
('skillset', 'Skillset'),
)
search = CharField(required=False)
filter_field = ChoiceField(choices=FILTER_CHOICES)
Then your view (views.py):
class HomeView(ListView):
model = Consultant
template_name = 'home.html'
def get_queryset(self):
query = self.request.GET.get('search')
filter_field = self.request.GET.get('filter_field')
# Do your filter and search here
return Consultant.objects.all()
def get_context_data(self, *args, **kwargs):
context = super().get_context_data(*args, **kwargs)
context['form'] = FilterForm(initial={
'search': self.request.GET.get('search', ''),
'filter_field': self.request.GET.get('filter_field', ''),
})
return context
and finally your template (templates/home.html):
<form class="row">
{{ form.search }}
{{ form.filter_field }}
<input type="submit" class="btn btn-default" value="Search">
</form>
Hope that would be helpful!
For the first issue, if there is nothing in the database it is returning an empty queryset so if you include
{% if object_list %}
do stuff
{% else %}
No results match your search
{% endif %}
For the second it depends on what you're trying to do, but let's suppose it is a
specific field you're searching.
search_choice = self.request.GET.get('filter')
choice_query = Q(search_field=search_choice)
Then simply add this to your query
views.py
class HomeView(generic.ListView):
model = Consultant
template_name = 'sogeti/home.html'
def get_queryset(self):
queryset = super().get_queryset()
q = self.request.GET.get('q')
if q:
queryset = queryset.filter(
Q(first_name__icontains=q) |
Q(last_name__icontains=q) |
Q(group__title_techGroup__contains=q) |
Q(practices__title_practice__contains=q)
)
filter = self.request.GET.get('filter')
if filter == 'people':
pass
elif filter == '...':
# do sth
return queryset
html
<form action="" method="get" class="form-inline">
<input type="text" name="q" placeholder="Enter Keyword" value="{{ request.GET.q }}" class="form-control">
<select name="filter" class="form-control">
<option value="all">All</option>
{% if request.GET.filter == 'people' %}
<option value="people" selected>People</option>
{% else %}
<option value="people">People</option>
{% endif %}
{% if request.GET.filter == 'certification' %}
<option value="certification" selected>Certification</option>
{% else %}
<option value="certification">Certification</option>
{% endif %}
{% if request.GET.filter == 'skillset' %}
<option value="skillset" selected>Skillset</option>
{% else %}
<option value="skillset">Skillset</option>
{% endif %}
</select>
<input type="submit" value="Search" class="btn btn-default">
</form>
<ol style="padding-left: 15px">
{% for consultant in object_list %}
<li>
{{ consultant.first_name }}, {{ consultant.last_name }} </br>
Technology Group: {{ consultant.group }} </br>
Primary Practice: {{ consultant.practices }}
<hr style="margin-left: 0">
</li>
{% empty %}
No result match q=`<b>{{ request.GET.q }}</b>` & filter=`{{ request.GET.filter }}`
{% endfor %}
</ol>

Not getting score in my mcq app- Django

For my MCQ app, I created a view
def process_data(request):
question_set=Question.objects.all()
choice_list=[]
question_set
for k, v in request.POST.items():
if k.startswith('choice'):
choice_list.append(v)
i=0
score=0
print type(question_set)
for question in question_set:
if question.answer1==choice_list[i]:
#print question.answer1
i=i+1
score=score+1
return HttpResponse(score)
html page contains the form look like this.
{% extends 'quiz/base.html' %}
{% block content%}
<h1>You are at quiz page</h1>
<form action="{% url 'quiz:process_data' %}" method="post">
{% csrf_token %}
{% for question in question_set %}
<h3>{{question.question_no}}.{{question.question_text }}</h3>
<input type="radio" name="choice{{ question.question_no}}" value="{{ question.option1 }}">{{ question.option1 }}<br>
<input type="radio" name="choice{{ question.question_no}}" value="{{ question.option2 }}">{{ question.option2 }}<br>
<input type="radio" name="choice{{ question.question_no}}" value="{{ question.option3 }}">{{ question.option3 }}<br>
<input type="radio" name="choice{{ question.question_no}}" value="{{ question.option4 }}">{{ question.option4 }}<br>
<input type="radio" name="choice{{ question.question_no}}" value="{{ question.option5 }}">{{ question.option5 }}<br>
{% endfor %}
<input type="Submit" name="Submit">
</form>
{% endblock%}
and this is the model for Questions
class Question(models.Model):
question_no=models.IntegerField(default=0)
question_text=models.CharField(max_length=1000)
option1=models.CharField(max_length=100)
option2=models.CharField(max_length=100)
option3=models.CharField(max_length=100)
option4=models.CharField(max_length=100)
option5=models.CharField(max_length=100)
answer1=models.CharField(max_length=100)
def __str__(self):
return self.question_text
The problem is that the score is not getting correctly. So that I tested it with the print statement and realized that only first questions answer is getting. How can I get the score correctly? Thank you
The problem is with how you have handled this call request.POST.item. The call to item function returns an unordered dictionary. This is causing your second for-loop to match user inputs against wrong question. Below is a sample code of what I mean:
user_inputs = request.POST.items() # key: choice<question_no> and value: <user_choice>
for question in question_set:
user_choice = user_inputs.get('choice'+question.question_no)
if user_choice == question.answer1:
//count the score

list the unicode array separately in template in python

The Following is my view.py
def UpdatePage(request):
templatevar = {}
user_name = request.session['login_user_email']
update_form = Update_Page()
if user_name:
home_page_form = Home_Page
templatevar['varobj']=models.ProfileDetail.objects.filter(email=user_name)
if request.method=='POST':
update_name=request.POST['name']
update_age=request.POST['age']
update_gender=request.POST.get('gender')
update_interested_in=request.POST.getlist('interested_in')
for i in update_interested_in:
print i
update_dob=request.POST.get('dob')
update_country=request.POST['country']
update_about_you=request.POST['about_you']
update_profile_detail=models.ProfileDetail.objects.filter(email=user_name).update(name=update_name,age=update_age,gender=update_gender,
interested_in=update_interested_in,dob=update_dob,country=update_country,about_you=update_about_you)
if update_profile_detail:
details_updated="Your Profile Details are Updated"
return HttpResponseRedirect('homepage',{'details_updated':details_updated})
return render(request,'update.html',{'user_name':user_name,'update_form':update_form,'templatevar':templatevar})
The Following is my Template View
<html>
<head>
<title>Update Here</title>
</head>
<body style="text-align:center">
<h3 style="text-align:right"><div>Home</div><div>Log Out</div></h3>
{{user_name}}
<h3>Update Here</h3>
<!--{{update_form.as_p}}-->
{% for all in templatevar.varobj %}
<p>Age:{{all.age}}<br></p>
<p>Gender:{{all.gender}}<br></p>
<p>Interested In:{{all.interested_in}}<br></p>
{%for i in all.interested_in%}
{{i}}
{%endfor%}
<p>DOB:{{all.dob}}<br></p>
<p>Country:{{all.country}}<br></p>
<p>About You:{{all.about_you}}<br></p>
{% endfor %}
<form action="" method="post">
{% csrf_token %}
{% for all in templatevar.varobj %}
<p><label for="id_name">People Call You As:</label> <input id="id_name" name="name" type="text" value="{{all.name}}" /></p>
<p><label for="id_email">Your Email:</label> <input id="id_email" name="email" type="email" value="{{user_name}}" readonly /></p>
<p><label for="id_age">Age:</label> <input id="id_age" name="age" type="number"value="{{all.age}}" /></p>
<p><label for="id_gender_0">Gender:</label> <ul id="id_gender">
<li><label for="id_gender_0"><input id="id_gender_0" name="gender" type="radio" value="Male" {% if all.gender == "Male" %}checked="checked"{% endif %} /> Male</label></li>
<li><label for="id_gender_1"><input id="id_gender_1" name="gender" type="radio" value="Female" {% if all.gender == "Female" %}checked="checked"{% endif %} /> Female</label></li>
<p><label for="id_interested_in_0">Interested In:</label>
<ul id="id_interested_in">
<li><label for="id_interested_in_0">
<input id="id_interested_in_0" name="interested_in" type="checkbox" value="Sports" {% if all.interested_in == "Sports" %}checked="checked"{% endif %}/> Sports</label></li>
<li><label for="id_interested_in_1"><input id="id_interested_in_1" name="interested_in" type="checkbox" value="Music" {% if all.interested_in == "Music" %}checked="checked"{% endif %} /> Music</label></li>
<li><label for="id_interested_in_2"><input id="id_interested_in_2" name="interested_in" type="checkbox" value="Gardening" {% if all.interested == "Gardening" %}checked="checked"{% endif %}/> Gardening</label></li>
<p><label for="id_dob">Date Of Birth:</label> <input id="id_dob" name="dob" type="text" value="{{all.dob}}" placeholder = "YYYY-MM-DD" /></p>
<p><label for="id_country">Your From:</label> <select id="id_country" maxlength="3" name="country">
<option value="India">India</option>
<option value="Australia">Australia</option>
<option value="America">America</option>
</select></p>
<p><label for="id_about_you">About You:</label> <textarea cols="40" id="id_about_you" name="about_you" rows="10" value="">{{all.about_you}}
</textarea></p>
{% endfor %}
<input type="submit" value="Update" />
</form>
</body>
</html>
The following is my model view:
class ProfileDetail(models.Model):
name = models.CharField(max_length=100,null=True)
email = models.EmailField(max_length=50,unique=True,null=True)
age = models.IntegerField(max_length=3,null=True)
gender = models.CharField(max_length=10,null=True)
interested_in = models.CharField(max_length=10,null=True)
dob = models.DateField(null=True)
country = models.CharField(max_length=25,null=True)
about_you = models.CharField(max_length=200,null=True)
def __str__(self):
return self.interested_in
I need to display the check box value separately as
Sports
Music
Gardening
and not the following
Interested In:[u'Sports', u'Music', u'Gardening']
How to display separately and check the values
Your error is that you are trying to store a list into a char field, that's why you are seeing the repr of the list.
First, in your view, change the line:
update_interested_in=request.POST.getlist('interested_in')
to
update_interested_in = ','.join(request.POST.getlist('interested_in'))
Then add a method to your model.py that splits the string:
class ProfileDetail(models.Model):
...
def interested_in_list(self):
return self.interested_in.split(',')
You can then use the join template filter:
{{ all.interested_in_list|join:"<br/>"|safe }}
If you have to construct the checkboxes yourself, you can use something like:
{% for interest in all.interested_in_list %}
<input name="interested_in" type="checkbox" value="{{ interest }}"> {{ interest }}
{% endfor %}

Categories

Resources