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

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

Related

How to append the values of text input into a List in jinja.flask

I am trying to append all the option data into a list. Using a list in the jinja flask.But i am not getting any idea on How to Append the data into the desired list.
HTML CODE:
{{ options=[] }}
{% for j in range(4) %}
<div class="input-group input-group-sm mb-3">
<span class="input-group-text" id="inputGroup-sizing-sm">Options {{j+1}}</span>
<input type="text" class="form-control" name='option' aria-label="Sizing example input" aria-describedby="inputGroup-sizing-sm">
</div>
{% endfor %}

How to make a checkbox checked in Jinja2

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!

How to pass form id if there are several forms on page and no submit buttons Django 1.10?

I have a page with list of questions. Each of them has radio button form with "Yes", "Maybe", "No" kind of choices. This form's submits by making a choice.
http://prntscr.com/embo1m
I can't understand how to connect question id with it's form. How to get it in it's view with response?
models.py
class Answer(models.Model):
user = models.ForeignKey(User)
apartment = models.ForeignKey(Apartment)
question = models.ForeignKey(Question)
choice = models.IntegerField(default=2)
def __str__(self):
return str(self.choice)
views.py
def questions_list(request, apartment_pk):
context = {}
context['apartment'] = get_object_or_404(Apartment, pk=apartment_pk)
context['questions'] = get_list_or_404(Question)
context['answer_form'] = AnswerForm
context['username'] = auth.get_user(request).username
if request.method == 'POST':
form = AnswerForm(request.POST or None)
if form.is_valid():
print(form.cleaned_data)
return render(request, 'main/questions.html', context)
forms.py
class AnswerForm(ModelForm):
choice = ChoiceField(label='', widget=RadioSelect, choices=ANSWERS)
question_id = CharField(widget=HiddenInput(), required=False)
class Meta:
model = Answer
fields = ('choice', 'question_id')
template
<h1>{{ apartment.title }}</h1>
{% for question in questions %}
<h3>{{ question.title }}</h3>
<form id="question_{{ question.id }}" name="question_{{ question.id }}" action="/apartments/{{ apartment.id }}/" method="post">
{% csrf_token %}
{% for radio in answer_form.choice %}
<label><input name="choice" type="radio" value="{{ radio.choice_value }}" onchange="question_{{ question.id }}.submit()">{{ radio.choice_label }}</label>
{% endfor %}
{{ answer_form.hidden_field }}
</form>
{% endfor %}
EDIT:
Tried to pass question id as <input type="hidden" name="q_id" value="{{ question.id }}">
<h1>{{ apartment.title }}</h1>
{% for question in questions %}
<h3>{{ question.title }}</h3>
<form id="question_{{ question.id }}" name="question_{{ question.id }}" action="/apartments/{{ apartment.id }}/" method="post">
{% csrf_token %}
<input type="hidden" name="q_id" value="{{ question.id }}">
{% for radio in answer_form.choice %}
<label><input name="choice" type="radio" value="{{ radio.choice_value }}" onchange="question_{{ question.id }}.submit()">{{ radio.choice_label }}</label>
{% endfor %}
</form>
{% endfor %}
And changed my form to
class AnswerForm(Form):
choice = ChoiceField(label='', widget=RadioSelect, choices=ANSWERS)
But there's no hidden input in form from response...
<tr><th></th><td><ul id="id_choice">
<li><label for="id_choice_0"><input id="id_choice_0" name="choice" type="radio" value="0" required /> Точно ні</label></li>
<li><label for="id_choice_1"><input id="id_choice_1" name="choice" type="radio" value="1" required /> Скоріше ні</label></li>
<li><label for="id_choice_2"><input checked="checked" id="id_choice_2" name="choice" type="radio" value="2" required /> Не можу відповісти</label></li>
<li><label for="id_choice_3"><input id="id_choice_3" name="choice" type="radio" value="3" required /> Скоріше так</label></li>
<li><label for="id_choice_4"><input id="id_choice_4" name="choice" type="radio" value="4" required /> Точно так</label></li>
</ul></td></tr>
Cleaned data {'choice': '2'}
Pass the question id as hidden value as shown below:
<input type="hidden" name="q_id" value="{{ question.id }}">
{% for radio in answer_form.choice %}
<label><input name="choice" type="radio" value="{{ radio.choice_value }}" onchange="question_{{ question.id }}.submit()">{{ radio.choice_label }}</label>
{% endfor %}

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