-1

I'm trying to display text and image on template from SQLite database. Database model:

class NewProduct(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    product_name = db.Column(db.String(100), nullable=False)
    product_description = db.Column(db.String(200), nullable=False)
    product_date = db.Column(db.DateTime, default=datetime.utcnow)
    product_img = db.Column(db.BLOB())

    def __repr__(self):
        return '<NewProduct %r>' % self.id

Function to display information from db in .html:

@app.route('/products')
def products():
    products = NewProduct.query.order_by(NewProduct.product_date.desc()).all()
    product_img = b64encode(products.product_img).decode('utf-8')
    return render_template('products.html', products=products, image=product_img)

HTML:

<body>
{% if products|length > 0 %}

    {% for el in products %}
        <p>Name: {{ el.product_name }}</p>
        <p>Description: {{ el.product_description }}</p>
        <p>Image: </p> <img src="data:;base64,{{ image }}">
        <p>Date: {{ el.product_date }}</p>
    {% endfor %}

{% else %}
    <p>There are have no products</p>
{% endif %}

So, I'm get an error: AttributeError: 'list' object has no attribute 'product_img' in line product_img = b64encode(products.product_img).decode('utf-8')

I did it for this answer. But I anyway get this error. What I'm doing whong and how can I fix that?

h4cktivist
  • 73
  • 3
  • 13

2 Answers2

2

products is a list so the line products.product_img raise the error you are facing. If you need to convert the image into something else you need to loop over the products and modify the image of each product.

balderman
  • 22,927
  • 7
  • 34
  • 52
1

You are trying to access product_img for a list of products, not on a single object. You need to iterate through the objects and update the value for each of them:

@app.route('/products')
def products():
    products = NewProduct.query.order_by(NewProduct.product_date.desc()).all()
    for product in products:
        product.product_img = b64encode(product.product_img).decode('utf-8')
    return render_template('products.html', products=products)

Then update your template to get the value from the product object:

<body>
{% if products|length > 0 %}

    {% for el in products %}
        <p>Name: {{ el.product_name }}</p>
        <p>Description: {{ el.product_description }}</p>
        <p>Image: </p> <img src="data:;base64,{{ el.product_img }}">
        <p>Date: {{ el.product_date }}</p>
    {% endfor %}

{% else %}
    <p>There are have no products</p>
{% endif %}

I would also suggest to remove the prefix product_ from your variables, as it seems redundant and makes your code less readable.