My code is not returning the desired output. Where am I going wrong?

Viewed 85

The following is the code for the route info:

@app.route("/", methods=["GET", "POST"])
def index():
    if current_user.is_authenticated:
        posts = Image.query.all()
        for post in posts:
            print(post.post_name)
        # print(current_user.is_moderator)
        return render_template("index.html", current_user=current_user, posts=posts)
    else:
        posts = Image.query.all()
        return render_template("index.html", posts=posts)

The following is the template:

<html>
    <head>
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <link rel="stylesheet" href="{{ url_for('static', filename='index.css') }}">

    </head>
    <body>
        {% with messages = get_flashed_messages() %}
            {% if messages %}
                {% for message in messages %}
                    <div class="flash-msg">{{ message }}</div>
                {% endfor %}
            {% endif %}
        {% endwith %}
        <script src="{{ url_for('static', filename='index.js') }}"></script>
        <div id="first">
        <input type="text" id="searchBar" name="searchBar">
        {% if current_user.is_authenticated %}
            <a href="{{ url_for('user', username=current_user.username) }}"><img src="{{ url_for('static', filename='profile-icon.png') }}" alt="" id="profileIcon"></a>
            <a href="{{ url_for('logout') }}" id="logout-btn">Logout</a>

        {% else %}
            <a href="{{ url_for('login') }}"><img src="{{ url_for('static', filename='profile-icon.png') }}" alt="" id="profileIcon"></a>
        {% endif %}
        </div>
        <div>
            {% for post in posts %}
                {% if loop.changed(current_post) %}
                    <div>
                        <a href="{{ url_for('read', post_name=post.post_name) }}">
                        <img src="{{ url_for('static', filename='images/'+post.title) }}" alt="">
                        </a>
                    </div>
                    <!-- <div>{{ current_post }}</div>
                        <div>{{ current_post }}</div> -->
                {% else %}
                    {% set current_post = post.post_name %}
                    <div></div>
                {% endif %}
            {% endfor %}

        </div>
    </body>
</html> 

Upon running the code in the route info, this was the output of the for loop:

Hz7g5LlonYWG
Hz7g5LlonYWG
Hz7g5LlonYWG
Hz7g5LlonYWG
dHjeIv8guNVE
dHjeIv8guNVE
dHjeIv8guNVE
dHjeIv8guNVE
ZcLji2uNgT1V

This is the code for the table Image:

class Image(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title=db.Column(db.String(120), nullable=False)
    date_posted = db.Column(db.DateTime, nullable=False, default=datetime.datetime.utcnow)
    img_location = db.Column(db.String(600), nullable=False)
    mimetype = db.Column(db.String(10))
    post_name = db.Column(db.String(150), nullable=False, unique=False)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)

Now the problem I am having is that in the template whose code I showed above, it is only rendering out one tag for one value of post_name. As per the code I wrote, it was supposed to render out a tag for every UNIQUE value of post_name. As clearly shown in the output of the for loop, there are 3 unique values of post_name stored inside of my database. What I mean to say is that the following code should be executed whenever there post.post_name's value is different from the previous iteration's post.post_name value:

                    <div>
                        <a href="{{ url_for('read', post_name=post.post_name) }}">
                        <img src="{{ url_for('static', filename='images/'+post.title) }}" alt="">
                        </a>
                    </div>

However, what is actually being executed is the code in the else block when it technically shouldn't be executed when post.post_name's value is different from its value in the previous iteration. How can I fix this? Please help me.

1 Answers

The problem is that the assignments cannot escape their defining block. So current_post variable defined in the else branch will not show up at the if checking block next cycle. However the solution is very simple, you don't even need to create a new variable, just use post.post_name at the changed test:

{% for post in posts %}
    {% if loop.changed(post.post_name) %}
        <div>
            <a href="{{ url_for('read', post_name=post.post_name) }}">
              <img src="{{ url_for('static', filename='images/'+post.title) }}" alt="">
            </a>
        </div>
    {% else %}
        <div></div>
    {% endif %}
{% endfor %}
Related