Send table data from template to view.py in django - python

I am passing a list i.e data_code from view.py to a html file and from there i am printing the data of the table using for loop through the list. There is a editable column in the table <input> and i want to get those data after filled by user on my view.py. so anybody any idea how to do that??
I want to get all {{x.2}} in view.py. It is printing some default value but i want it again after it is being by user.
Here is the code:
<table class="table table-bordered datatable">
<thead class="table-head">
<tr>
<th>No</th>
<th>Code Point</th>
<th>Reference</th>
<th>Character</th>
<th>Text</th>
<th>Description</th>
</tr>
</thead>
<tbody>
{% for x in data_code %}
<tr class="table-row">
<td>{{ forloop.counter }}</td>
<td><label>{{ x.0 }}</label></td>
<td><input id="codepoint_input" type="text" value={{x.2}} size=3 title="Text"></td>
<td><label> {{x.3}}</label></td>
<td>{{x.4}}</td>
</tr>
{% endfor %}
</tbody>
</table>

Edit:
Use dictionary type so that you can give each input box a unique name through the key, and use the corresponding value in value parm.
In view, you can use a for loop to go through the whole dictionary, and use the key to get the values from the template.
In your Template:
<form name = "yourForm" method="GET" action="/" class = "main">
{% for key, value in json.data_code%}
<td>
<input name = "{{ key }}" id="codepoint_input" type="text" value={{ value }} size=3 title="Text">
<input type="submit" id = "amountbtn" style="visibility:hidden;" >
</td>
{% endfor %}
</form>
In your views:
key1 = request.GET.get('key1')
....

The first task is get those entered values using jquery simply...
$(#codepoint_input).keypress(function(e) {
if(e.which == 13) {
// your custom code here.
var tablestring = $("#tableForm").serialize();
$.post( "/backend", tablestring );
}
});
Finally you can get the values in your view function...
def backend(request):
print(request.POST)

Related

Searching data in text file for output and convert to table dataframe

in advanced sorry if I have any mistake during reading my questions:
I'm working with Django and python for my website.
The process I need to read input from the user for searching the directory file that I want to read which is I take 2 input, input1, and input2.
I set the keyword in the variable if the keyword is matching I will print the next line.
THIS IS MY TEXT FILE
delay_index_time
775435
delay_index_time
456345
delay_index_time
4567867867868
delay_index_time
567867
Python Code In views.py
def SearchBox(request):
fullpath = ""
input1= request.GET.get('input1')
input2= request.GET.get('input2')
input_combine = str(input1).upper() + "_" + str(input2)
summary = '1A'
search_string = 'delay_index_time'
if input_Lot is None:
return render(request, 'Output.html')
else:
path = "D:/file/" + str(input_combine) + "/" + summary
with open(path) as input_data:
for line in input_data:
if search_string in line:
context = {
"output": (next(input_data))
}
return render(request, 'Output.html', context)
Template HTML
<form id = "lol" class="navbar-form navbar-left" role="search" method="GET" action="">
<div class="input-group">
<input style="left:260px; width:250px; top:-80px;" id="box1" name="input1" type="text" class="form-control" placeholder="Lot">
<input style="left:270px; top:-80px; width:250px;" id="box2" name="input2" type="text" class="form-control" placeholder="Operation">
<div style="left:540px; top:-101px;" class="input-group-btn">
<button id = "search_sub" value="Search" class="btn btn-default" type="submit"><i class="glyphicon glyphicon-search"></i></button>
</div>
</div>
</form>
{{ output|safe }}
{% endblock %}
My issue is it only print the first line of the output which is:
775435
But the other 3 output not display.
456345
4567867867868
567867
EXTRA QUESTION
How if i want the output display in table form in one column on my website.
NEW QUESTION
This is data in my text file.
I will display the string after I found 'id_' which is the id user.
Display the id user in one column.
Then, under id user got delay_index_time which I will display next line of the output.
But sometimes delay_index result will have more than one result.
I will zip it/combined in one table with 2 column.
It will display using a check box selection. if let's say user only want to view user id it will only display that. if the user ticks both of it in check box it will display both of it in the table.
For the check box, I have no idea on it. Sorry if I'm asking a lot of question :(
id_A1
delay_index_time
s_7754
s_7731
id_A2
delay_index_time
mrs_7745
id_A3
delay_index_time
s_77789
id_A4
delay_index_time
s_7752
This is my coding in views.py
context = {}
with open(path) as input_data:
for line in input_data:
if line.startswith('id_'):
if 'output' in context:
context['output'].append(line.lstrip('id_').rstrip())
if search_string in line:
if 'output1' in context:
context['output1'].append(next(input_data).lstrip('s_').rstrip())
context = {
'output': [(line.lstrip('id_').rstrip())],
'output1': [(next(input_data).lstrip('s_').rstrip())]
}
return render(request, 'Output.html', context)
This is my templates
<div class="container" style=" width:170px;">
<table style="" class="table table-bordered">
<thead class="success" >
<th class="active"><b>Visual ID</b></th>
{% for line in output1 %}
<tr class="success">
<td>{{ line }}</td>
</tr>
{% endfor %}
</thead>
<thead class="success" >
<th class="active"><b>Time Delay</b></th>
{% for line in output %}
<tr class="success">
<td>{{ line }}</td>
</tr>
{% endfor %}
</thead>
</table>
views.py
Templates
Try this, it works for me.
context = {}
with open(path) as input_data:
for line in input_data:
if search_string in line:
if 'output' in context:
context['output'].append(next(input_data))
else:
context = {'output': [(next(input_data))]}
return render(request, 'Output.html', context)
And to display output in a tabular form.
<table>
<tr>
<th>Output</th>
</tr>
{% for line in output %}
<tr>
<td>{{ line }}</td>
</tr>
{% endfor %}
</table>

Finding the sum of numbers in jinja2 template using flask

I am learning flask and tried to create a web app that accepts a student's name and marks, finds the total of all the marks and display things in a table. But the total always gets displayed as 0.
The code is given below
mark_total.py:
from flask import Flask, render_template, request
app = Flask (__name__)
#app.route('/')
def student():
return render_template('student.html')
#app.route('/result', methods = ['POST', 'GET'])
def result():
if request.method == 'POST':
result = request.form
return render_template('result.html', result = result)
if __name__ == '__main__':
app.run(host = '0.0.0.0', debug = True)
student.html:
<form action = "/result" method = "POST">
<p>Name <input type = "text" name = "Name" /></p>
<p>Physics <input type = "text" name = "Physics" /></p>
<p>Chemistry <input type = "text" name = "chemistry" /></p>
<p>Maths <input type ="text" name = "Mathematics" /></p>
<p><input type = "submit" value = "submit" /></p>
</form>
</body>
</html>
result.html:
<html>
<head>
<title>Results</title>
</head>
<body>
<h1>{{result["Name"]}}'s results</h1>
{% set total = 0 %}
<table border = 1>
{% for key, val in result.iteritems() %}
{% if key != 'Name' %}
{% set total = total|int + val|int %}
<tr>
<td>{{ key }}</td>
<td>{{ val }}</td>
<td>{{ total }}</td>
</tr>
{% endif %}
{% endfor %}
<tr>
<td>Total</td>
<td>{{total}}</td>
</tr>
</table>
</body>
</html>
The html source of the output is as follows:
<html>
<head>
<title>Results</title>
</head>
<body>
<h1>ABC's results</h1>
<table border = 1>
<tr>
<td>Mathematics</td>
<td>100</td>
<td>100</td>
</tr>
<tr>
<td>chemistry</td>
<td>100</td>
<td>100</td>
</tr>
<tr>
<td>Physics</td>
<td>100</td>
<td>100</td>
</tr>
<tr>
<td>Total</td>
<td>0</td>
</tr>
</table>
</body>
</html>
Can someone please help me understand how to solve this?
The problem is that your total defined inside the loop is not the same total defined (and accessed) outside of loop. This is what local scopes do.
You can overcome this by using a hack like this (adapted from this answer).
<html>
<head>
<title>Results</title>
</head>
<body>
<h1>{{result["Name"]}}'s results</h1>
{% set total = [0] %}
<table border = 1>
{% for key, val in result.iteritems() %}
{% if key != 'Name' %}
{% set _ = total.append(total.pop() + val|int) %}
<tr>
<td>{{ key }}</td>
<td>{{ val }}</td>
<td>{{ total[0] }}</td>
</tr>
{% endif %}
{% endfor %}
<tr>
<td>Total</td>
<td>{{ total[0] }}</td>
</tr>
</table>
</body>
</html>
But I'm really not sure that it is a good idea to do such things in a template. The main idea of templates is to separate the logic (like counting the totals) and the representation, and this is a violation of this principle.
When you change variable value inside a loop does not effect outside of the loop except a dict:
{% set total = {'value': 0} %}
...
{% if total.update({"value": c|int + total.value|int }) %} {% endif %}
...
{{total.value}}

How to make form handler of checkbox, Python, Django

I have a problem: I want to make checkboxes of each line of table:
<form action="" method="post">
{% csrf_token %}
<table>
<thead>
<tr>
<th>cb</th>
<th width="150">first_col</th>
<th>sec_col</th>
<th width="150">third_col</th>
</tr>
</thead>
<tbody>
{% for i in list %}
<tr>
<td><input type="checkbox" name="choices" value="{{i.id}}"></td>
<td>{{ i.created_date}}</td>
<td> {{ host }}/{{i}}/ </td>
<td>{{i.number_of_clicks}}</td>
</tr>
{% endfor %}
</tbody>
</table>
<button type="submit" name="delete" class="button">Del</button>
</form>
And in the def I make next in order to check if it works:
if 'delete' in request.POST:
for item in request.POST.getlist('choices'):
print (item)
But it does not print anything... What do i do wrong? Or can you help me to write correct handler of checkboxes?
First you should check for request.method == 'POST' rather than for the submit button name in request.POST. Though, that shouldn't be the problem why you don't see anything. From what you posted I don't know what's not working but here's an example that shows how you could achive what you want. It assumes your template is in test.html:
# This is just a dummy definition for the type of items you have
# in your list in you use in the template
import collections
Foo = collections.namedtuple('Foo', ['id', 'created_date', 'number_of_clicks'])
def test(request):
# check if form data is posted
if request.method == 'POST':
# simply return a string that shows the IDs of selected items
return http.HttpResponse('<br />'.join(request.POST.getlist('choices')))
else:
items = [Foo(1,1,1),
Foo(2,2,2),
Foo(3,3,3)]
t = loader.get_template('test.html')
c = RequestContext(request, {
'list': items,
'host': 'me.com',
})
return http.HttpResponse(t.render(c))

How to get data from a form to jinja2

I am trying to get a value inputted through a form and then back into my jinja template. Which I know doesn't make sense so I guess I am asking how do I go about doing what I want?. Here is what I have:
Python
#app.route('/test', methods=['GET', 'POST'] )
def test():
posts = db.posts
facultyId = request.form.get("facultyId","");
print "facultyId: ",facultyId
return render_template('form.html',posts=posts,Id=facultyId)
form.html
<form method='post'>
<table width="80%" border="5" align="center" bgcolor="white">
<tbody>
<tr>
<th colspan= "4">
Faculty Identification Number:
<input type="text" id="facultyId" name="facultyId" value=""/>
</th>
</tr>
<tr>
<th colspan= "4">
Number Of Evaluations:
{% if posts.find({"Applicants.appId" : Id},{'Applicants.Evaluators':{'$exists': True }}).count() == 0 %}
{{posts.find({"Applicants.appId" : Id},{'Applicants.Evaluators':{'$exists': True }}).count() }}
{% else %}
{% for post in posts.find({"Applicants.appId" : Id}, { "Applicants.$.Evaluators" : 1 }) %}
{{post["Applicants"][0]["Evaluators"]|length}}
{% endfor %}
{% endif %}
</th>
</tr>
<th colspan= "4"><button type="submit" >Submit</button></th>
</tbody>
</table>
</form>
I want to be able to submit a facultyId though a form and have it go into my jinja and run my mongodb find query. It works if I hard code the value in so if I did Id=100 in my python it works but if I do it though the forums it doesn't and the facultyId value is getting inputted because it does prints out.
Try to set action controller as follows
<form method='post' action='/test'>
I think the problem is that you do not parse facultyId as an integer. It works if you hardcode 100, because it is an integer, but what you assign out of request.form is a string "100".
After
facultyId = request.form.get("facultyId","")
add
facultyId = int(facultyId) if facultyId else None
Try to put it in braces. Like this:
<form method='post'>
<table width="80%" border="5" align="center" bgcolor="white">
<tbody>
<tr>
<th colspan= "4">
Faculty Identification Number:
<input type="text" id="facultyId" name="facultyId" value=""/>
</th>
</tr>
<tr>
<th colspan= "4">
Number Of Evaluations:
{% if posts.find({"Applicants.appId" : {{Id}}},{'Applicants.Evaluators':{'$exists': True }}).count() == 0 %}
{{posts.find({"Applicants.appId" : {{Id}}},{'Applicants.Evaluators':{'$exists': True }}).count() }}
{% else %}
{% for post in posts.find({"Applicants.appId" : {{Id}}}, { "Applicants.$.Evaluators" : 1 }) %}
{{post["Applicants"][0]["Evaluators"]|length}}
{% endfor %}
{% endif %}
</th>
</tr>
<th colspan= "4"><button type="submit" >Submit</button></th>
</tbody>
</table>
</form>
I would also suggest to put your posts.find logic into your route function, then pass it's results to your form in the posts variable.

Using Flask and WTForms how can i have a table where some columns are inputs?

I'm struggling to see how this is done, and the documentation doesn't seem to help much.
I need to generate a table, the row size will be variable, but not dynamic (i know how much rows i need before generating the page).
For the sake of simplicity lets imagine a page where you grade n exams with an integer.
i tried this:
the form.
class InputInteger(Form):
grade = IntegerField('Grade')
the view
#decorator..
def grade():
form = InputInteger()
names = student_list
return render_template("grade.html", form=form, names=names)
the template
<table>
<tr>
<th>Name</th>
<th>Grade</th>
</tr>
{% for name in names %}
<tr>
<td>
{{name}}
</td>
<td>
{{form.grade}}
</td>
</tr>
</table>
But how do i read back the inputed values?
How do i distinguish who's grade that belongs too?
Am fairly confused, i've read about FieldList(FormField(IntegerField)), but isn't that just one field with a list of integers?
What about the Table Widget, do i need that?
Please help.
For anyone looking at this now, the OP was correct to think about FieldLists and FormFields. Here is a solution:
forms.py:
class GradeForm(FlaskForm):
student = IntegerField('Student ID')
grade = IntegerField('Grade')
delete = BooleanField('Delete')
class GradeFormSet(FlaskForm):
gradeset = FieldList(FormField(GradeForm), min_entries=0)
view.py:
def grade():
# create a dict of student IDs and their initial grades (or None for now)
init_merits = [dict(student=s.id, grade=None) for s in myStudentTable.query.all()]
gradeform = GradeFormSet(gradeset=init_merits)
if form.validate_on_submit():
...
# meritforms.data['gradeset'] contains a list of dictionary values for further processing
# check 'delete' == True to handle deletion of that student from your table
...
return render_template('template.html', form=gradeform)
Template:
<table>
{% for merit in form.gradeset %}
<tr>
<td>{{ merit.placing(readonly=true) }} {{ merit.csrf_token }} {{ merit.hidden_tag() }}</td>
<td>{{ merit.grade }}</td>
<td>{{ merit.delete }}</td>
</tr>
{% endfor %}
</table>
<input type="submit" name="finish" value="Save">
<input type="submit" name="cancel" value="Cancel">
You're almost right. Put your table inside a html form and catch in a function where you can retrieve your input fields.
Here is an example:
<form action="/grade">
<table>
<tr>
<th>Name</th>
<th>Grade</th>
</tr>
{% for name in names %}
<tr>
<td>{{name}}</td>
<td><input id='{{name}}' value='{{ form.grade }}'></td>
</tr>
</table>
</form>
And your Flask function:
#app.route('/grade', methods=['GET', 'POST'])
def grade():
if request.method == 'POST':
return 'Form posted.'
When you post your form to your function, you can access your input field by this way: request.form['inputfieldname'] and then you do your stuff. I hope my explanation is clear.

Categories

Resources