tedioustortoise
tedioustortoise

Reputation: 269

Flask SQLAlchemy unable to update single value in db

When the tick button is pressed, I would like that post status to be marked as “complete.”

enter image description here

I have tried a simple post.status = “completed” and also some sqlalchemy

routes.py:

@app.route("/post/<int:post_id>/markcomplete", methods=['POST'])
def mark_complete(post_id):
    post = Post.query.get_or_404(post_id)
    # post.status = "completed"
    db.session.query(post).filter(post.id == post_id).update({post.status:"completed"})
    db.session.commit()
    return redirect(url_for('home'))

Other app routes, such as edit post, and delete post are working fine. The edit post is performed on wtforms, where the status is a SelectField - either “ongoing” or “completed.” The delete route is working with no issues:

@app.route("/post/<int:post_id>/delete", methods=['POST'])
def delete_post(post_id):
    post = Post.query.get_or_404(post_id)
    db.session.delete(post)
    db.session.commit()
    flash('Your post has been deleted', 'danger')
    return redirect(url_for('home'))

models.py

class Post(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    title = db.Column(db.String(100), nullable=False)
    date_posted = db.Column(db.DateTime, nullable=False, default=datetime.utcnow)
    description = db.Column(db.Text, nullable=False)
    status = db.Column(db.String(100), nullable=False)
    priority = db.Column(db.String(100), nullable=False)
    assigned_to = db.Column(db.String(100), nullable=False)
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
    reported_by = db.Column(db.String(100), nullable=False)

    def __repr__(self):
        return f"Post('{self.title}', '{self.date_posted}')"

home.html


{% block content %}
    <div class="Blocks">
        <div id="First">
        <p align="right">
        <a class="btn btn-primary" class="nav-item nav-link"  href="{{ url_for('all') }}" role="button">Show All</a>
        <a class="btn btn-primary" class="nav-item nav-link"  href="{{ url_for('new_post') }}" role="button">New Post</a>
        <a class="btn btn-primary" data-toggle="collapse" href="#collapseExample" role="button"
        aria-expanded="false" aria-controls="collapseExample">Quick Expand</a>
        </p>
        <table style="leftside" align="center">
              <tr style="border-bottom:1pt solid black;">
                <th>Title</th>
                <!--<th>Status</th>-->
                <th>Priority</th>
                <th>Datetime</th>
                <th>Assigned To</th>
                <th>Reported By</th>
                <th>Edit</th>
                <th></th>
                <th></th>
              </tr>
             {% for post in posts %}
                {% if 'ongoing' in post.status %}
                    <tr>
                        <td><a class="article-title" href="{{ url_for('post', post_id=post.id) }}">{{ post.title }}</a></td>
                        <!--<td>{# {{ post.status }} #}</td>-->
                        <td>{{ post.priority }}</td>
                        <td><strong><small>{{ post.date_posted }}</small></strong></td>
                        <td><small>{{ post.assigned_to }}</small></td>
                        <td><small>{{ post.reported_by }}</small></td>
                        <td><a class="btn btn-primary" class="article-title" href="{{ url_for('update_post', post_id=post.id) }}">Edit</a></td>
                        <td><a class="btn btn-primary" class="article-title" href="{{ url_for('mark_complete', post_id=post.id) }}">&#10003;</a></td>

                   {% endif %}
                        <td colspan="5">
                            <div class="collapse" id="collapseExample"><div class="card card-body">{{ post.description }}</div></div>
                        </td>
                    </tr>
              {% endfor %}
        </table>
    </div>
{% endblock content %}

The error: Method Not Allowed The method is not allowed for the requested URL.

Upvotes: 0

Views: 57

Answers (1)

Abhishek Kulkarni
Abhishek Kulkarni

Reputation: 1767

Try this :

All the url_for links are GET requests.

@app.route("/post/<int:post_id>/markcomplete", methods=['GET', 'POST'])
def mark_complete(post_id):
    post = Post.query.get_or_404(post_id)
    post.status = "completed"
    db.session.add(post)
    db.session.commit()
    return redirect(url_for('home'))

Upvotes: 1

Related Questions