I need to replicate the functioning of Flaskr example (the minimal blog application),
but instead of populating the fields of the output with the database contents I am getting those values from a text file in the disk.
I am not sure how to read values from a text file and print them, here is the code used to retrieve values from the DB:
{% extends "layout.html" %}
{% block body %}
{% if session.logged_in %}
<form action="{{ url_for('main') }}" method=get,post class=main>
<dl>
<dt>Available:
<dd><input type=text size=15 name=available>
<dt>Used frequency:
<dd><input type=text size=15 name=used>
<dd><input type=submit value=Update>
</dl>
</form>
{% endif %}
<table border="1" style="width:300px">
<ul class=localDB>
<tr>
</ul>
<th></th>
<th>MyValues</th>
<th>maxValue</th>
</tr>
<tr>
<th>Available</th>
<td>{% for entry in localDB %} {{ entry.available }} {% endfor %}</td>
<td>N/A</td>
</tr>
<tr>
<th>Used</th>
<td>{% for entry in localDB %} {{ entry.used }} {% endfor %}</td>
<td>N/A</td>
</tr>
</ul>
</table>
{% endblock %}
Do I have to use other tools like JavaScript or I can use Flask and get the result I want.
here's how to read from a file and split the first and second lines.
file = open('newfile.txt', 'r')
available = file.read().split('\r\n')[0]
used = file.read().split('\r\n')[1]
print file.read()
Hope this Helps!
Related
#app.route('/',methods = ['POST'])
def user_rating():
for i in form_value['Rating']:
print(request.form.get(str(i)))
return("Thank You")
I tried various methods but they are not working. Is there any way to iterate over form name and get their value
Above is the code I am working on and want to get data from multiple forms with a single button. But able to get only the first value from the form.
HTML code:
<tbody>
{% for record in records %}
<tr>
{% for col in colnames %}
<td>
{% if (col != 'poster_link') and ( col != 'Rating' ) %}
{{ record[col] }}
{% endif %}
<!--Movie Poster-->
{% if col == 'poster_link' %}
<img src={{ record[col] }} style="width:150px">
{% endif %}
<!--end of Movie Poster-->
<!--form Rating-->
{% if col == 'Rating' %}
**<form method="post" id="FORMID" action="{{url_for('user_rating')}}">
<input type="text" name= {{ record[col] }} placeholder="Give Rating 1 to 5" >
</form>**
{% endif %}
<!--end of form Rating-->
</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
<button type="submit" form="FORMID" value="Submit">Submit</button>
Getting output like this
1
None
None
None
None
None
None
None
None
None
That is not possible because a user can only submit one form on a page. Whichever form is submitted is the one that gets read by your backend code. What you should do is either:
Use AJAX to make a request every time the input is changed, or
Only use one form
Based on your code, it appears that it will be easier to just use one form. So something like this would work:
<form method="post" id="FORMID" action="{{url_for('user_rating')}}">
<table>
<tbody>
{% for record in records %}
...
<input type="text" name= {{ record[col] }} placeholder="Give Rating 1 to 5" >
...
{% endfor %}
</tbody>
</table>
<button type="submit" form="FORMID" value="Submit">Submit</button>
</form>
I have a for loop within my Django project, what I'am trying to do is the following :
If
morning_recess == True
lunch_recess == True
afternoon_recess == True
then the bootstrap tag in that field should be
<td><span class="badge badge-success">Success</span></td>
else
<td> None </td>
Here is my current code:
<table style="width:100%">
<tr>
<th>Student Name</th>
<th>Morning Recess</th>
<th>Lunch Recess</th>
<th>Afternoon Recess</th>
<th>Earned At</th>
</tr>
<tr>
{% for i in students_recess_today %}
{% if i.morning_recess == True %}
<td>{{i.student_ps }}</td>
<td><span class="badge badge-success">Success</span></td>
<td>{{i.lunch_recess}}</td>
<td>{{i.afternoon_recess}}</td>
<td>{{i.created_at}}</td>
{% else %}
<td>{{i.student_ps }}</td>
<td>None</td>
<td>{{i.lunch_recess}}</td>
<td>{{i.afternoon_recess}}</td>
<td>{{i.created_at}}</td>
{% endif %}
</tr>
{% endfor %}
</table>
</div>
The morning_recess works fine, however if i do another if statement after the following one, the order of my table gets all messed up. How do I write this correctly? Thank you
It's not clear what "in that field" means, because in your example you have one extra column before the morning_recess column. But you can put {% if %} statements anywhere you want in the template, e.g.:
<td>
{% if i.morning_recess %}
<span class="badge badge-success">Success</span>
{% else %}
<span>None</span>
{% endif %}
</td>
<td>
{% if i.lunch_recess %}
<span class="badge badge-success">Success</span>
{% else %}
<span>None</span>
{% endif %}
</td>
<td>
{% if i.afternoon_recess %}
<span class="badge badge-success">Success</span>
{% else %}
<span>None</span>
{% endif %}
</td>
...
Also as other commenters suggest, your for loop should probably wrap the rows of your table (<tr>...</tr>), not the columns (<td>).
You have the loop partially inside your tr element. It starts a row at the beginning and for every student adds the columns and ends a row, so it ends up looking like <tr></tr></tr></tr>.
You should move your for statement outside of the row, like so:
...
{% for i in students_recess_today %}
<tr>
...
</tr>
{% endfor %}
</table>
</div>
I want to use the template to create all the tables of my project, but after writing is appearing errors like this:
jinja2.exceptions.TemplateSyntaxError: expected token ':', got '}'
{{ table(headers={{headers}},items={{item}},url='None') }}
I've looked at the jinja2 website but couldn't find the answer to the syntax error.
# python
#app.route('/products')
def products():
context = {}
qproducts = list(s.query(Product))
context['products'] = qproducts
return render_template('products.html', **context)
# table.html
{% macro table(headers,items,url,var) -%}
<table class='table table-sm table-dark'>
<thead>
<tr>
{{headers}}
</tr>
</thead>
<tbody>
{% for item in items %}
<tr onclick="window.location='{{url}}'">
{{items}}
</tr>
{% endfor %}
</tbody>
</table>
{%- endmacro %}
# products.html
{% from 'table.html' import table %}
{% block headers %}
<th>ID</th>
<th>Price</th>
{%endblock headers%}
{%block item%}
{%for item in products%}
<td>{{item.id}}<td><br>
<td>{{item.price}}<td><br>
{%endfor%}
{%endblock item%}
{{ table(headers={{headers}},items={{item}},url='None') }}
Even when you fix the references to variables (i. e. remove surrounding {{/}}) it won't work the way you expect. block tag can only be used with extends tag, but you use import for macros importing. If you want to write universal macro for table rendering it's better to use combination of macro/call tags:
{% macro table(headers,items,url,var) -%}
<table class='table table-sm table-dark'>
<thead>
<tr>
{{ caller(mode='header') }}
</tr>
</thead>
<tbody>
{% for item in items %}
<tr onclick="window.location='{{url}}'">
{{ caller(mode='row', item) }}
</tr>
{% endfor %}
</tbody>
</table>
{%- endmacro %}
caller here is a reference to a special function which invokes externally-provided callback. Then you can call this macro this way:
{% call(mode, items) table(headers=headers, items=item, url='None') %}
{% if mode='header' %}
<th>ID</th>
<th>Price</th>
{% else %}
{%for item in products%}
<td>{{item.id}}<td><br>
<td>{{item.price}}<td><br>
{% endfor %}
{% endif %}
{% endcall %}
Every mention of caller in macro table invokes body of the caller tag with the specified parameters. So, you can customize the behavior of the macro.
Okay, I'll try to make it short.
I got an XML file from Musicbrainz. Then I converted it to CSV and replaced the .'s with _'s to make it work with Liquid.
I put music.csv in _data and call it with:
{% include music.html %}
_includes/music.html looks (in part) like:
<table border="1" style="width:100%">
<tr>
<td>Artist</td>
<td>Track title</td>
</tr>
<tr>
{% if member.release_medium-list_medium_track-list_track_0_recording_artist-credit_name-credit_artist_name %}
<td>{{ member.release_medium-list_medium_track-list_track_0_recording_artist-credit_name-credit_artist_name }}</td>
{% endif %}
{% if member.release_medium-list_medium_track-list_track_0_recording_title %}
<td>{{ member.release_medium-list_medium_track-list_track_0_recording_title }}</td>
{% endif %}
</tr>
<tr>
{% if member.release_medium-list_medium_track-list_track_1_recording_artist-credit_name-credit_artist_name %}
<td>{{ member.release_medium-list_medium_track-list_track_1_recording_artist-credit_name-credit_artist_name }}</td>
{% endif %}
{% if member.release_medium-list_medium_track-list_track_1_recording_title %}
<td>{{ member.release_medium-list_medium_track-list_track_1_recording_title }}</td>
{% endif %}
</tr>
<tr>
{% if member.release_medium-list_medium_track-list_track_2_recording_artist-credit_name-credit_artist_name %}
<td>{{ member.release_medium-list_medium_track-list_track_2_recording_artist-credit_name-credit_artist_name }}</td>
{% endif %}
{% if member.release_medium-list_medium_track-list_track_2_recording_title %}
<td>{{ member.release_medium-list_medium_track-list_track_2_recording_title }}</td>
{% endif %}
</tr>
Now, clearly, this is not the best way to do it. What I'm after is something that:
Looks for the relevant data
If the data is there, creates the cells and fills them out.
I'm pretty sure this can be done with Liquid, but I have no idea how. Can someone here help?
EDIT: Turns out I forgot the CSV file -- here it is, on Pastebin.
EDIT 2: This Cheat Sheet might be of help!
The format of a CSV file inherently does not support repeated sections so I think it would be a bad fit for the variable length data format you are trying to use. I feel JSON is more appropriate for this use case as it can handle the structure of the source data you are trying to work with.
As a quick example I put the XML file you supplied through this converter to create a JSON version of the output. This was saved as "_data/music.json".
This liquid code was then used to parse this:
{% for item in site.data.music %}
<h2> {{ item[1].release.title }}</h2>
{% for medium in item[1].release.medium-list %}
<h3> {{ medium[1].format }} </h3>
<table border="1" style="width:100%">
<tr>
<td>Artist</td>
<td>Track title</td>
</tr>
{% for track in medium[1].track-list.track %}
<tr>
<td>{{ track.recording.artist-credit.name-credit.artist.name }}</td>
<td>{{ track.recording.title }}</td>
</tr>
{% endfor %}
</table>
{% endfor %}
{% endfor %}
This produces HTML like this (trimmed):
<h2> The Quatermass Film Music Collection</h2>
<h3> CD </h3>
<table border="1" style="width:100%">
<tr>
<td>Artist</td>
<td>Track title</td>
</tr>
<tr>
<td>Tristram Cary</td>
<td>Quatermass and the Pit: Opening Credits</td>
</tr>
<tr>
<td>Tristram Cary</td>
<td>Quatermass and the Pit: Bones</td>
</tr>
</table>
Based on this you should be able to produce the format you ultimately want.
This is a simple way to iterate over a csv file.
<div class="table-responsive">
<table class="table">
<thead>
<tr>
{% for column in include.datafile[0] %}
<th>{{ column[0] }}</th>
{% endfor %}
</tr>
</thead>
<tbody>
{% for spec in include.datafile %}
<tr>
{% for value in spec %}
<td>{{ value[1] }}</td>
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
</div>
I'm building an ecommerce site with django, and i wanted to create a button that would signal that an order had already been delivered.
I'm pretty sure you can acheive this with a checkbox, but i wanted to use a button, because it would be easier to click when using a tablet.
I want the button to also be "unclickable" in case someone accidentally clicked a button for a wrong order.
Do i need to make a form in the html? or is there an easier way to do it.
this is my html:
Order page
<table>
<tr>
<td>#</td>
<td>Name</td>
<td>Email</td>
<td>Phone</td>
<td>Order</td>
<td>Order Quantity</td>
<td>Delivered</td>
</tr>
{% for ord in orders %}
{% for food in ord.orderitem_set.all %}
<tr>
{% if forloop.counter == 1 %}
<td>{{ord.pk}}</td>
<td>{{ord.user.first_name}}</td>
<td>{{ord.user.email}}</td>
<td>{{ord.user.get_profile.phone}}</td>
{% else %}
<td colspan="4"></td>
{% endif %}
<td>{{food.name}}</td>
<td>{{food.quantity}}</td>
<td>{% if forloop.counter == 1 %} <button type="button">Delivered</button> {% endif %}</td>
</tr>
{% endfor %}
{% endfor %}
</table>
</body>
</html>
hmm, I think just putting a form around the button would be the "easier way" ^^
later if you wanted to, you could make it a spiffy javascript toggle using almost the same view code below maybe
e.g. around your buttons...
<form action="{% url show_orders %}" method="post">
<input type="hidden" name="order-id" value="{{ ord.pk }}"/>
<input type="hidden" name="action=" value="toggledelivery"/>
<button type="button">{% if not ord.is_delivered %}Not {% endif %}Delivered</button>
</form>
then in your view, something like...
def show_orders(request):
if request.method == "POST":
order_id = request.POST.get('order-id', None)
# TODO toggle the order here
return HttpResponseRedirect(back_to_the_order_admin_page)
else:
# ...show the admin page