2
\$\begingroup\$

I'm making a really basic website where users essentially just submit data into some forms and they will be able to review their data in another page. I feel like I'm going to be repeating myself far too much.

This is how I'm planning to display the users records, the trouble I'm having is I have about six more tables of data that is slightly different. So I can't just hard-code a template because the number of columns and the names of the columns is slightly different in each table. I know I could just make six different HTML files but that just seems silly. I feel like I need to somehow loop over the attributes of the models and then somehow display them in the template?

Is there a better way of displaying database data in a template?

class (db.Model):
    __abstract__ = True
    employee_name =  db.Column(db.String(50), nullable=False)
    date_submitted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    comment =  db.Column(db.String(100), nullable=True)


class FridgeFreezerTempTable(Base):
    id = db.Column(db.Integer, primary_key=True)
    unit_name = db.Column(db.String(50), nullable=False)
    unit_type = db.Column(db.String(50), nullable=False)
    temperature = db.Column(db.String(10), nullable=False)
    company_id = db.Column(db.Integer, db.ForeignKey('user.id'),nullable=False)

@app.route("/unit_temp_records/<int:page_number>")
def unit_records(page_number):
    """
    records = pagiantion object
    page number = the current page
    
    """
    records = FridgeFreezerTempTable.query.filter_by(user=current_user).paginate(per_page=5,                             
             page=page_number, error_out=True)
    return render_template("unit_temp_records.html", user_records=records, table=table)

{% extends "records.html"%}
<!--This is garbage, find a way to make all below a template.. dir? __dict__???-->
{%block recordcontent%}
<table class="table table-striped">
    <thead>
        <tr>
            <th scope="col">#</th>
            <th scope="col">Unit Name</th>
            <th scope="col">Unit Type</th>
            <th scope="col">Temperature</th>
            <th scope="col">Employee Name</th>
            <th scope="col">Comment</th>
            <th scope="col">Date Submitted</th>
        </tr>
    </thead>

    <tbody>
        {% for record in user_records.items %}
            
            <tr>
                <th scope="col">{{ loop.index }}</th>
                <td>{{record.unit_name}}</td>
                <td>{{record.unit_type}}</td>
                <td>{{record.temperature}}</td>

                <td>{{record.employee_name}}</td>
                <td>{{record.comment}}</th>
                <td>{{record.date_submitted}}</td>
            </tr>
        {% endfor %}
    </tbody>

    <!-- Also garbage (maybe figure out how to put this into records template -->
    {% for page in user_records.iter_pages() %}
    {% if page %}
    <a class="test" href="{{url_for('unit_records', page_number=page) }}">{{ page }}</a>
    {% else %}
    .
    {% endif %}
    {% endfor %}
</table>
{% endblock%}
```
\$\endgroup\$
1
  • 5
    \$\begingroup\$ The site standard is for the title to simply state the task accomplished by the code, not your concerns about it. Please see How do I ask a good question? for examples, and revise the title accordingly. \$\endgroup\$
    – Martin R
    Commented Dec 20, 2019 at 19:21

1 Answer 1

1
\$\begingroup\$

Perhaps the templates can be generated by a function. Pass in a list of the attribute names, and it returns a template string. Or pass in the table name, and query the column names to make the template. Then use render_template_string() instead of render_template().

This code is rough and untested, but outlines what I'm thinking:

def column_headers(attrs):
    headers = (f'<th scope="col">{attr.replace("_"," ").titlecase()}</th>' 
               for attr in attrs)
    return '\n'.join(headers)

def columns(attrs):
    column_refs = (f'<td>{{record.{attr}}}</td>' for attr in attrs)
    return '\n'.join(column_refs)

def make_template(attrs):
    template_string = ["""
        {% extends "records.html"%}
        {%block recordcontent%}
        <table class="table table-striped">
            <thead>
                <tr>
                """,
                column_headers(attrs),
                """
            </thead>
            <tbody>
                {% for record in user_records.items %}
                <tr>
                    <th scope="col">{{ loop.index }}</th>
                    """,
                    columns(attrs),
                    """
                </tr>
                {% endfor %}
            </tbody>
        </table>
        {% endblock%}
        """]
        return '\n'.join(template_string)

FridgeFreezerTemplate = make_template("""
                                      unit_type
                                      temperature
                                      employee_name
                                      comment
                                      date_submitted
                                      """.strip().split())

@app.route("/unit_temp_records/<int:page_number>")
def unit_records(page_number):
    """
    records = pagiantion object
    page number = the current page

    """
    records = FridgeFreezerTempTable.query.filter_by(user=current_user).paginate(per_page=5,                             
             page=page_number, error_out=True)
    return render_template_string(FridgeFreezerTemplate, user_records=records, table=table)
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.