helloflask / bootstrap-flask

Bootstrap 4 & 5 helper for your Flask projects.
https://bootstrap-flask.readthedocs.io
Other
1.1k stars 189 forks source link

unable to access fields of relationship via render_table #280

Open SchnitzelKopf opened 1 year ago

SchnitzelKopf commented 1 year ago

Hi,

I am unable to access product.name in my html. When using the "for item loop" I am able to print item.product.name. However in titles when using product.name it will remain empty. Typing only 'product' will correctly display <Product 1>.

What am I doing wrong?

app.py

@app.route('/cost_calculation/<int:cost_calculation_id>/view')
def view_cost_calculation(cost_calculation_id):
    # Details of Calculation
    cost_calculation = CostCalculation.query.get(cost_calculation_id)

    cost_calculation_items = CostCalculationItem.query.filter_by(cost_calculation_id=cost_calculation_id).all()
    from pprint import pprint
    pprint(cost_calculation_items)
    for item in cost_calculation_items:
        pprint(item)
        print(f"{item.product.name}: {item.unit_price}")
        print(f"{item.product.product_detail}: {item.unit_price}")

    titles = [('id', '#'),('product', 'Product Name'),('name', 'Product Name'),('product.name', 'Product Name'), ('quantity', 'Quantity'), ('unit_price', 'Price')]

    return render_template('cost_calculation_view.html', 
                            cost_calculation=cost_calculation, 
                            cost_calculation_items=cost_calculation_items, 
                            CostCalculationItem=CostCalculationItem,
                            titles=titles)

Log:

[<CostCalculationItem 1>, <CostCalculationItem 2>]
<CostCalculationItem 1>
Virtual Server (EC2): 10
Dummy product description for Virtual Server (EC2): 10
<CostCalculationItem 2>
Database (RDS): 5

html:

{{ render_table(cost_calculation_items, titles=titles, primary_key='id', urlize_columns=(''), show_actions=True, model=CostCalculationItem,
view_url=('view_cost_calculation_item', [('cost_calculation_item_id', ':id')]),
edit_url=('edit_cost_calculation_item', [('cost_calculation_item_id', ':id')]),
delete_url=('delete_cost_calculation_item', [('cost_calculation_item_id', ':id')]),
new_url=url_for('list_products'))}}

model:

class Product(db.Model):
    __tablename__ = 'product'

    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(), nullable=False)
    product_price = db.Column(db.DECIMAL, nullable=False)
    product_detail = db.Column(db.String())
    # cost_calculation_item = db.relationship('CostCalculationItem')

class CostCalculationItem(db.Model):
    __tablename__ = 'cost_calculation_item'

    id = db.Column(db.Integer, primary_key=True)
    description = db.Column(db.String(), nullable=True)
    quantity = db.Column(db.Integer, nullable=False)
    unit_price = db.Column(db.DECIMAL, nullable=False)
    cost_calculation_id = db.Column(db.Integer, db.ForeignKey('cost_calculation.id'), nullable=False)
    cost_calculation = db.relationship('CostCalculation', backref='cost_calculation_items')

    product_id = db.Column(db.Integer, db.ForeignKey('product.id'), nullable=False)
    product = db.relationship('Product', backref='cost_calculation_items')
VonUniGE commented 1 year ago

The problem comes from flask_bootstrap/templates/base/table.html: https://github.com/helloflask/bootstrap-flask/blob/dc0b91ec229d3562bde1e63625a0bbfc9e415fa3/flask_bootstrap/templates/base/table.html#L79-L83

In your case, you have key = 'product.name' and in Jinja2 row['product.name'] is not resolved as intended.