creating flask table from data - python

I'm being trying to put data into a table in flask but its creating a new row for each character for some reason instead of just putting the full string into the row.
code:
#app.route('/')
def logs():
output = ''
try:
conn = redis.StrictRedis(host='redis', port=6379)
for key in conn.scan_iter("log.g*"):
value = str(conn.get(key))
output += "str(key)+ '--' + value"
return render_template('view.html', data=output)
table code:
<table>
{% for row in data %}
<tr>
{% for value in row %}
<td>{{ value }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>

Well, the thing is that your output / data is absolutely unstructured - it is just one big string. You want to make for example a list:
output = []
conn = redis.StrictRedis(host='redis', port=6379)
for key in conn.scan_iter("log.g*"):
value = str(conn.get(key))
output.append("str(key)+ '--' + value")
return render_template('view.html', data=output)
(In your code your return statement is inside the cycle, which means that the cycle will run just once.
The code above will create a list and then the template:
<table>
{% for value in data %}
<tr>
<td>{{ value }}</td>
</tr>
{% endfor %}
</table>
will print each list member into a table cell. Aside of that, we cannot tell what you want to have in one table row.

Related

Unable to return json values retrieved from MongoDB to HTML page in python flask

I'm able to retrieve required value from MongoDB individually and also able to print same values but unable to return all those values to HTML page. When I try to return those values I'm able to see only first value though I have used for loop in jinja.
My code is as follows:
#app.route('/webhookdisplay', methods=['POST', 'GET'])
def webhooksdis():
collection10 = db['webhooks']
a = collection10.find({"name": "abc"}, {'_id': 0, 'recorded_at':0, 'expiry_time': 0, 'version': 0, 'created_at': 0, 'account_id': 0, 'device_id': 0})
for i in collection10.find({}):
d = i.get('data', {}).get('geometry', {}).get('coordinates')
print(d)
name = i.get('data', {}).get('geofence_metadata', {}).get('name')
print(name)
return render_template("webhooks.html", name = name, a = a, d =d)
In the above code name has None values also, so when I try to return it individually shows TypeError: 'NoneType' object is not iterable. Suppose if I return those values which dowsn't have None values it gets returned but displays only first value.HTML code
{% for i in d %}
{{ i }}
{% endfor %}<br />
This jinja works for all values but I require for individual values which I'm retrieving in flask:
<table>
<th>
{% for item in a %}
</th>
<tr>
<td><th> {% for key, value in item.items() %} </th> </td>
<td><span>{{ key }} : {{ value }}</span> </td>
<br />
<td>{% endfor %}</td>
<td>{% endfor %}</td>
</tr>
</table>
**Expected Output** All values including None values should be returned which I'm retrieving in flask so that I can render in HTML page
You can use jinja for template rendering.
Using below pseudo code you can populate JSON data:
{% for key, value in a %}
<span>{{key}} : {{value}}</span>
{% endfor %}
What is the output of:
print(request.data)
print(request.form)
print(request.json)
print(request.get_json())
?
UPDATE:
a is a list. So try:
{% for item in a %}
{% for key, value in item.items() %}
<span>{{ key }} : {{ value }}</span><br />
{% endfor %}
{% endfor %}
if a:
filtered_data=[{"name":device["name"]} for device in a]
print(filtered_data)
else:
print("Document does not exist !")

Cant Turn Tuple Into String

I am struggling to display two columns (resultlist) in seperate columns. Right now when i return result list its showing in a tuple. When i try to index the for loop(to remove the tuple) with i[0] in the HTML file but i get the first character which is the "("
current output:
column1
('123456', '150.92')
('49815', '70.43')
('19971', '39.35')
If i try to index the for loop in html, current output:
column1
(
(
(
expected output:
Column1 Column2
123456 150.92
49815 70.43
19971 39.35
Current python file:
def subtractboth(alloclist, statementlist):
resultlist = []
for i, j in zip(statementlist, alloclist):
if i[0] == j[0]:
results = float(j[1]) - float(i[1])
if results >= 0:
results = i[0], "{:.2f}".format(results)
print(" ".join(results))
resultlist.append(str(results))
return resultlist
#app.route('/results', methods=['GET', 'POST'])
def main():
connect()
masteracct = request.args.get('masteracct')
cashdt = request.args.get('cashdt')
billdt = request.args.get('billdt')
allocation(connect(), cashdt, masteracct)
statement(connect(), billdt, masteracct)
a = subtractboth(statement(connect(), billdt, masteracct), allocation(connect(), cashdt,
masteracct))
html = render_template('test_results.html', a=a)
return html
HTML:
<table>
<th>Column 1</th>
<th> Column 2</th>
{% for i in a %}
<tr>
<td>{{i}}</td>
<td>{{i}}</td>
</tr>
{% endfor %}
</table>
The Jinja2 template for displaying a table with 2 columns should look like this:
<table>
<tr>
<th>column1</th>
<th>column2</th>
</tr>
{% for v1, v2 in a %}
<tr>
<td>{{ v1 }}</td>
<td>{{ v2 }}</td>
</tr>
{% endfor %}
</table>
The variable a should be a sequence of pairs.

Skip first row when rendering table data with Jinja

I have a list representing rows of data. The first item in the list is the column names. When I render the rows using Jinja, I don't want to render the column names, because generating a url for that makes no sense. How can I skip the first row while rendering?
array = [
['one','two','three'],
[0,12,13],
[1,22,16],
[5,66,21],
[2,55,44]
]
#app.route('/')
def index():
return render_template('test.html', table=array)
{% for item in table %}
<tr>
<td>{{ item[0] }}</a></td>
<td>{{ item[1] }}</td>
<td>{{ item[2] }}</td>
</tr>
{% endfor %}
if all you want is for the template to skip the 1st entry in the array, simply pass to it the appropriate slice of your array, i.e.:
return render_template('test.html', table=array[1:])

Best way to store data(table) and easy acces to represent it

I'm working with the django framework and I found a way to store the data that I recieved by a RPC call. This data follow the JSON format:
{"header":["data_enviament","nom_auditor","matricula","bastidor"],"data":[{"data_enviament":"05/1/2014","nom_auditor":"Brutus Brutus, Marc","matricula":"1234FRX","bastidor":"192891478kjhda"},{"data_enviament":"05/2/2014","nom_auditor":"Pepito Rudolf, Margarita","matricula":"2234FRX","bastidor":"192891478kjhda"},{"data_enviament":"05/5/2014","nom_auditor":"Patrick Linda, Judith","matricula":"5234FRX","bastidor":"192891478kjhda"}],"count":2}
And I store this data into a matrix( at the controller point ), the code is:
for i in range(len(tabla['header'])):
array[0][i] = tabla['header'][i]
x = 1
for data in tabla['data']:
for i in range(len(tabla['header'])):
array[x][i] = data[array[0][i]]
x = x + 1
Then I parse this data by the render function to the template and represent into a html table.
I'm doing fine or there are maybe another way to do it better?
You can transform the data into a list of lists keeping the order of the items according to the header.
Demo from the shell:
>>> from django.template import Template, Context
>>> data = {"header":["data_enviament","nom_auditor","matricula","bastidor"],"data":[{"data_enviament":"05/1/2014","nom_auditor":"Brutus Brutus, Marc","matricula":"1234FRX","bastidor":"192891478kjhda"},{"data_enviament":"05/2/2014","nom_auditor":"Pepito Rudolf, Margarita","matricula":"2234FRX","bastidor":"192891478kjhda"},{"data_enviament":"05/5/2014","nom_auditor":"Patrick Linda, Judith","matricula":"5234FRX","bastidor":"192891478kjhda"}],"count":2}
>>>
>>> data = [[item[header] for header in data['header']] for item in data['data']]
>>> c = Context({'data': data})
>>> template = """
<table>
{% for row in data %}
<tr>
{% for item in row %}
<td>{{ item }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
"""
>>> t = Template(template)
>>> print t.render(c)
<table>
<tr>
<td>05/1/2014</td>
<td>Brutus Brutus, Marc</td>
<td>1234FRX</td>
<td>192891478kjhda</td>
</tr>
<tr>
<td>05/2/2014</td>
<td>Pepito Rudolf, Margarita</td>
<td>2234FRX</td>
<td>192891478kjhda</td>
</tr>
<tr>
<td>05/5/2014</td>
<td>Patrick Linda, Judith</td>
<td>5234FRX</td>
<td>192891478kjhda</td>
</tr>
</table>

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