Iterating over submitted form fields in Flask? - python

In Flask 0.8, I know I can access individual form fields using form.fieldname.data, but is there a simple way of iterating over all the form fields? I'm building an email message body, and I'd like to loop over all the fields and create a fieldname/value entry for each, as opposed to manually building it by naming each field and appending.

I suspect that your are using WTForms.
You can iterate over form data:
for fieldname, value in form.data.items():
pass
You can iterate over all form fields:
for field in form:
# these are available to you:
field.name
field.description
field.label.text
field.data

The form object has an iterator defined on it:
{% for field in form %}
<tr>
{% if field.type == "BooleanField" %}
<td></td>
<td>{{ field }} {{ field.label }}</td>
{% else %}
<td>{{ field.label }}</td>
<td>{{ field }}</td>
{% endif %}
</tr>
{% endfor %}
This is from https://wtforms.readthedocs.io/en/2.3.x/fields/#wtforms.fields.Field.type

Related

Pass information from html form to python flask

I am new to flask and web applications, trying to create a web application that takes the name and the sport for each user and store it in sqlite DB, now Iam trying to remove users from the DB by taking the registrant id from the html to flask.
flask:
#app.route("/deregister")
def deregister():
value_from_html = ?????
db.excute("DELETE * FROM registrant WHERE id = ?", value_from_html)
html:
{% extends "layout.html" %}
{% block body %}
<h1>Registrant name</h1>
<tbody>
{% for registrant in registrants %}
<tr>
<td>{{ registrant.name }}</td>
<td>{{ registrant.sport }}</td>
<td>
<form action="/deregister" method="post">
<input name="id" type="hidden" value="{{ registrant.id }}"> !-- trying to pass registrant.id to flask --!
<input type="submit" value="Deregister">
</form>
</td>
</tr>
{% endfor %}
</tbody>
{% endblock %}
python code is not complete yet.
You can recieve the form data in the following way.
#app.route("/deregister", methods=['POST'])
#login_required
def deregister():
try:
if request.method == 'POST':
if request.files:
uploaded_file = request.files['filename']
data = uploaded_file.stream.read()
In order to send a variable to flask, you dont need to use forms, you can easily do that in the following way,
#app.route("/deregister/<string:id>", methods=['POST'])
#login_required
def deregister(id):
try:
variable = id
print(variable)
In html, keep this,
{% extends "layout.html" %}
{% block body %}
<h1>Registrant name</h1>
<tbody>
{% for registrant in registrants %}
<tr>
<td>{{ registrant.name }}</td>
<td>{{ registrant.sport }}</td>
<td>
<a href='/deregister/{{ registration.id }}'>Send Id</a>
</td>
</tr>
{% endfor %}
</tbody>
{% endblock %}
After trying to solve it my self finaly Ive found a way to do that:
1)Add button in my html to remove from DB:
I hope that this will help any one as it did for me.

Sorting by length in Jinja

I have table users that contain column username and entries (a one-to-many relationship with table entries). In my HTML file, I want to display the username and the number of entries from the particular user.
It looks like this:
{% for i in users %}
<tr>
<td>{{ i.username }}</td>
<td>{{ i.entries|length }}</td>
</tr>
{% endfor %}
I want to sort the rows from the user who has the biggest number of entries to the least.
I try this but it doesn't work:
{% for i in users|sort(entries|length) %}
How can I achieve this?
You should ideally create your query-set in you view and in your template, you can access it like so
{% for user in users|sort(attribute="length")
<tr>
<td>{{ user.username }}</td>
<td>{{ user.entries|length }}</td>
</tr>
{% endfor %}
Using length attribute on your item, you can do so with sort(attribute='length'). Taken from the Jinja2 sort filter documentation

How to take at template table one time photo next time string value

I want to make table where second element in every row is photo. Like here: http://www.uefa.com/worldcup/season=2014/standings/
I have all my values in list. In list, third element is photo's url. Other variables are just strings. How to write it in Django template?
Here is my code:
<table>
{% for row in data%}
<tr>
{% for value in row %}
<td>{{ value }}</td>
{% endfor %}
</tr>
{% endfor %}
</table>
I hope you will understand my problem.
Your {{ value }} for that second element should be a path (relative or absolute) to an image resource. If this data is defined by a model within your Django project, make sure the field is set correctly in models.py--it should be a FileField or ImageField. With those, you get a callable URL property. Then in your template, something along these lines:
<table>
{% for row in data%}
<tr>
{% for value in row %}
{% if value.url %}
<td><img src="{{ value.url }}" alt="..."></td>
{% else %}
<td>{{ value }}</td>
{% endif %}
{% endfor %}
</tr>
{% endfor %}
</table>

Using multiple for tags in tables with django

I'm fairly new to Django, and am working on a project where I have items appended to multiple lists and would like to display them in a table. I am using the for tag as there is quite a few items in each list. However, when i run my code, the first item on the list repeats over and over, then the second item repeats over and over, and so on. I have a feeling its because i used multiple for tags. Heres my code:
<table>
{% for x in result.netIncomeAr %}
{% for y in result.d2 %}
<tr>
<td>{{ x }}</td>
<td>{{ y }}</td>
</tr>
{% endfor %}
{% endfor %}
</table>
Any ideas where I went wrong? Thanks.
The inner loop should use the outer loop variable:
{% for x in result.netIncomeAr %}
{% for y in x.d2 %}
UPD (after looking at the result variable):
You need to change the result variable passed into the template, use zip() to join two lists:
result = zip(df['Date'], df['Net Income'])
return render_to_response('ui/search.html', {"result": result}, context)
Then, in the template iterate over the result this way:
<table>
{% for x in result %}
<tr>
<td>{{ x.0 }}</td>
<td>{{ x.1 }}</td>
</tr>
{% endfor %}
</table>

Django - complex nested list and tuple unpacking

This is simplified but it describes fundamentally what I'm trying to do.
In my views.py, I'm building a list of lists. Each list contains a store name, a list of (product, price) tuples, and a list of (employee, age) tuples. Both the tuple lists are of indeterminable length (but are the same length in each respective line). The outer list containing the name and tuple lists is also of indeterminable length.
[[store_name, [(product_1a, price_1a),(product_2a,price_2a),...], [(employee_1a, age_1a), (employee_2a, age_2a),...]]
[another_store_name, [(product_1b, price_1b),(product_2b,price_2b),...], [(employee_1b, age_1b), (employee_2b, age_2a),...]]
... ]
Each line of the above package needs to be unpacked into one row of a table in my template. I'm trying the following code for my template:
{% for name, products, employees in package %}
<tr>
<td>{{ name }}</td>
{% for product, price in products %}
<td>{{ product }}</td> <td>{{ price }}</td>
{% endfor %}
{% for employee, age in employees %}
<td>{{ employee }}</td> <td>{{ age }}</td>
{% endfor %}
</tr>
{% endfor %}
Actually - I've tried about a dozen different solutions and am at my wits end. Any help on how to repackage and unpack successfully in a template to achieve the desired goal would be most appreciated!
P.S. I'm not really working with store_names, products and employees but this seems the simplest way to put it in a post. I understand totally if you question the need to have this sort of data in one table row!
You can access array sequence elements in the template via arr.0, arr.1 etc. See documentation here: https://docs.djangoproject.com/en/1.4/topics/templates/#variables
So try something like this:
{% for item in package %}
<tr>
<td>{{ item.0 }}</td>
{% for product in item.1 %}
<td>{{ product.0 }}</td> <td>{{ product.1 }}</td>
{% endfor %}
{% for employee in item.2 %}
<td>{{ employee.0 }}</td> <td>{{ employee.1 }}</td>
{% endfor %}
</tr>
{% endfor %}

Categories