Render Flask tables depending on the model

Viewed 36

My app contains different db.models eg. (Customers Cameras ...). I would like to fill my template "tables.html" with data dynamically depending on the model called.

I succeeded to enter the headers but I struggle to populate the content of the table.

Normally the data would be populated by {{ data.cust_name }} or {{ data.cam_name }} etc. but obviously in my case it doesn't work.

I would be very grateful if someone could point me in the right direction?

models.py

class Customers(db.Model):
    cust_id = db.Column(db.Integer, primary_key=True)
    cust_name = db.Column(db.String, unique=True, nullable=False) ....

 def __repr__(self):
        return f"Customers( '{self.cust_name}','{self.cust_address}','{self.cust_zip}','{self.cust_city}','{self.cust_phone}','{self.cust_email}','{self.cust_active}',' {self.cust_timestamp.strftime('%d/%m/%Y %H:%M:%S')}')"

routes.py

 table = val
    match table:
        case "Customers":
            tableName = Customers
            tbl_prefix = "cust_"
        case "Cameras":
            tableName = Cameras
            tbl_prefix = "cam_"
        case "Endpicts":
            tableName = Endpicts
            tbl_prefix = "ep_"
        case "Extcalpoints":
            tableName = Extcalpoints
            tbl_prefix = "ecp_"
        case "Extrinsics":
            tableName = Extrinsics
            tbl_prefix = "ec_"
        case "Intrinsics":
            tableName = Intrinsics
            tbl_prefix = "ic_"
        case "Pumps":
            tableName = Pumps
            tbl_prefix = "pmp_"
        case "Rawpicts":
            tableName = Rawpicts
            tbl_prefix = "rp_"
        case "Stations":
            tableName = Stations
            tbl_prefix = "pst_"
        case "Settings":
            tableName = Settings
            tbl_prefix = "set_"
        case "Users":
            tableName = Users
            tbl_prefix = "usr_"
        case "Visits":
            tableName = Visits
            tbl_prefix = "vis_"
        case _:
            return redirect(url_for('login')) 
    cur = conn.cursor()
 #column headers
    try:
        columns=tableName.__table__.columns
        headings=[]
        for c in columns:
            heading=c.name.replace(tbl_prefix,"")
            headings.append(heading)
    except:
        conn.rollback()

    #columns
    if tableName == Users:
        try:
            cur.execute("SELECT * FROM " + tableName +" ORDER BY id")
            data = cur.fetchall()
        except:
            conn.rollback()
    else:
        try:
            n=[]
            data =  tableName.query.all()
            
        except:
            conn.rollback()

return render_template('tables.html', title=val, prefix=tbl_prefix, headings= headings,data=data, username=current_user.usr_name)

table.html

...
<table id="table" class="table table-hover">
            <thead>
                <tr class="theader">
                    {% for header in headings %}
                    <th class="table-cell"> {{header}} </th>

                    {% endfor %}
                    <th></th>
                    <th></th>
                </tr>
            </thead>
            
            <tbody class="tbody">
                {% for row in data %}
                

                <tr class="table-row" row_id="{{row[0]}} ">
                    {%for row in data %}
                    
                    
                    <td>
                        {% if row %}
                        <div input readonly="" class="row_data" edit_type="click"> {{ data.cust_name }}</div>
                        {% else %}
                        <div input readonly="" class="row_data" edit_type="click"> &nbsp;</div>
                        {% endif %}
                    </td>
                    {% endfor %}
                    <td>
                        <a id="btn_edit" class="btn_edit" row_id="{{row[0]}}"><i class="fa fa-pencil fa-1x"></i></a>
                        <a id="btn_save" class="btn_save" row-id="{{row[0]}}"><i class="fa fa-check fa-1x"></i></a>
                        <a id="btn_cancel" class="btn_cancel" row-id="{{row[0]}}"><i class="fa fa-xmark fa-1x"></i></a>
                        <a id="btn_delete" class="btn_delete" row-id="{{row[0]}}"><i class="fa fa-trash-o fa-1x"></i></a>
                    </td>
                </tr>
                {% endfor %}
            </tbody>
        </table>
...
1 Answers

I think that you have the problem in the template. data is an array of objects from any table. And iterating twice on it don't works. Try iterating the headers twice and accessing the object like a dict

<table id="table" class="table table-hover">
    <thead>
        <tr class="theader">
            {% for header in headings %}
            <th class="table-cell"> {{header}} </th>

            {% endfor %}
            <th></th>
            <th></th>
        </tr>
    </thead>
    
    <tbody class="tbody">
        {% for row in data %}
        
        {% set data_row = row.__dict__ %}

        <tr class="table-row" row_id="{{data_row[prefix+'id']}} ">
            {%for header in headings %}
            
            
            <td>
                {% if data_row[prefix+header] %}
                <div input readonly="" class="row_data" edit_type="click"> {{ data_row[prefix+header] }}</div>
                {% else %}
                <div input readonly="" class="row_data" edit_type="click"> &nbsp;</div>
                {% endif %}
            </td>
            {% endfor %}
            <td>
                <a id="btn_edit" class="btn_edit" row_id="{{data_row[prefix+'id']}}"><i class="fa fa-pencil fa-1x"></i></a>
                <a id="btn_save" class="btn_save" row-id="{{data_row[prefix+'id']}}"><i class="fa fa-check fa-1x"></i></a>
                <a id="btn_cancel" class="btn_cancel" row-id="{{data_row[prefix+'id']}}"><i class="fa fa-xmark fa-1x"></i></a>
                <a id="btn_delete" class="btn_delete" row-id="{{data_row[prefix+'id']}}"><i class="fa fa-trash-o fa-1x"></i></a>
            </td>
        </tr>
        {% endfor %}
    </tbody>
</table>
Related