Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Customize flask form as table

I've been biting my nails on this one for quite some time. In my Flask-app I currently have a product-database, for which in the app I have a page that queries each product column into a table.

For example I'd have product 1234 for which I could view the details (i.e. database columns) in example.com/items/1234 which would give me the following:

<div class="container">
  <div class="content">
  <a href="/item">Back</a>
  <table class="table">
  <thead>
    <tr>
      <th>#</th>
      <th>Value</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th scope="row">Detail-1<th>
      <td>Example</td>
    </tr>
    <tr>
       <th scope="row">Detail-2</th>
       <td>Example</td>
    </tr>

What I'm struggling with is the following:

I'd like to be able to add new products with same table-style. For this I have created a form like the following:

class NewArticleForm(FlaskForm):
    detail_1 = StringField("Detail-1")
    detail_2 = IntegerField("Detail-2")
    ...
    submit = SubmitField("Submit")

I am now at a total loss on how to customize the form appearance in the template beyond just {{ wtf.quick_form(form) }}. What I tried is the following:

<form method="POST">
<table class="table">
  {% for name in form %}
  <tr>
    <th scope="row">{{ name.label }}</th>
    <td>{{ name }}</td>
  </tr>
  {% endfor %}
 </table>
 </form>

The table looks good (at least that) but the request is not being sent correctly I presume. The page loads correctly with "POST /url HTTP/1.1" but it doesn't seem to come through correctly.

What I mean by that is that though the request is being sent correctly, as I can see if I run the app via the Flask server. However it seems that nothing is transmitted to the database. The page simply reloads with the entered data still in the fields and nothing transmitted to the database. If I simply use the wtf.quick_form then the data is correctly sent to the database.

So how can I correctly customize the form appearance and/or crucial step did I miss?

like image 319
rongon Avatar asked Jan 03 '18 18:01

rongon


1 Answers

Well this is embarrassing actually. I managed to solve it on my own and boy was it a dumb solution.

The reason nothing was transmitted to the database was that if some fields were left blank (that were not marked required in the form), they were interpreted as string-fields, which of course would give an error for Integer-fields.

The problem was that as you can see in my template code, I did not include the code to show any errors when submitting the fields. I changed my template code to this:

{% macro render_field(field) %}
  <th scope="row">{{ field.label }}
  <td>{{ field(**kwargs)|safe }}
  {% if field.errors %}
    <ul class=errors>
    {% for error in field.errors %}
      <li>{{ error }}</li>
    {% endfor %}
  {% endif %}
{% endmacro %}

<form method="POST">
<table class="table">
  {{ form.csrf_token }}
  {% for name in form %}
    <tr>
    {{ render_field(name) }}
    </tr>
  {% endfor %}
</table>
</form> 

I will now go bow my head in shame and hope that someday this might help someone.

like image 107
rongon Avatar answered Oct 24 '22 05:10

rongon