zEn feeLo
zEn feeLo

Reputation: 1978

If statement always True Jinja2 Template

I'm not sure what exactly the problem is but the concept is when my function execute it should fetch a query list from database and if It doesnt contain any object it should return False and the else part should execute

The first part works but even when my database is empty it passes True,

{% if new_bookmarks %}
     <div id='newBookmarks'>
        {% for bm in new_bookmarks %}
            <a href='{{ bm.url }}'><span>{{ bm.user.username }}</span> 
            Added: {{ bm.url }} <span>{{ bm.description }}</span></a>
        {% endfor %}
    </div>
{% else %}
    <div>
        Something else
    </div>
{% endif %}

@app.route('/')
@app.route('/index')
def index():
    return render_template('index.html', new_bookmarks=Bookmark.newest(5))

class Bookmark(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    url = db.Column(db.Text, nullable=False)
    date = db.Column(db.DateTime, default=datetime.utcnow)
    description = db.Column(db.String(300))
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)

    @staticmethod
    def newest(num):
        return Bookmark.query.order_by(desc(Bookmark.date)).limit(num)

Upvotes: 0

Views: 312

Answers (1)

kindall
kindall

Reputation: 184191

The problem is that a query is lazy, i.e., it doesn't execute until you begin iterating over it. Therefore it has no idea how many records are in it at the point you're testing its truthiness. By default most objects in Python are truthy, and this applies to queries as well.

To work around this, use:

return Bookmark.query.order_by(desc(Bookmark.date)).limit(num).all()

The .all() executes the query and puts the results into a list. Lists are falsy when they are empty. Since this is a small query, the drawbacks to having the results in memory all at once are minor.

Upvotes: 1

Related Questions