Hi I'm newbie to web development. I'm using flask and I have this ff. error:
"Could not build url for endpoint 'post'. Did you forget to specify values ['post_id']?"
I'm trying to redirect the page after deleting a comment in the post. But it brings me to "500 Internal Server Error" page and when I click the back button of my browser, the success flash msg is displayed and the comment was remove.
"routes.py"
@app.route("/post/<int:post_id>")
@login_required
def post(post_id):
post = Post.query.get_or_404(post_id)
return render_template("post.html", title="Post", post=post)
@app.route("/post-comment/<int:post_id>", methods=['GET','POST'])
@login_required
def comment_post(post_id):
post = Post.query.get_or_404(post_id)
form = CommentForm()
if form.validate_on_submit():
comment = Comment(body=form.body.data, post_id=post.id, author=current_user)
db.session.add(comment)
db.session.commit()
flash("Your comment has been added to the post", "success")
return redirect(url_for("comment_post", post_id=post.id, post=post))
return render_template("comment.html", title="Comment Post", post_id=post.id, post=post, form=form)
@app.route("/comment-delete/<int:comment_id>", methods=['POST'])
@login_required
def delete_comment(comment_id):
comment = Comment.query.filter_by(id=comment_id).first()
if comment.author != current_user:
abort(403)
db.session.delete(comment)
db.session.commit()
flash('Your comment has been deleted!', 'success')
return redirect(url_for('post'))
"post.html and comment.html" - both has url_for to delete_comment
{% for comment in post.comments %}
<table>
<tr>
<td>
{% if comment.author == current_user %}
<form action="{{url_for('delete_comment', comment_id=comment.id, post_id=post.id, post=post)}}" method="POST">
<input class="btn btn-danger" type="submit" value="Delete">
</form>
{% endif %}
<small class="text-muted">{{ comment.author.username }}</small>
<p class="mb-1">{{ comment.body }}</p>
</td>
</tr>
</table>
{% endfor %}
DB
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
username = db.Column(db.String(20), unique=True, nullable=False)
password = db.Column(db.String(60), nullable=False)
comments = db.relationship('Comment', backref='author', lazy=True)
posts = db.relationship('Post', backref='author', lazy=True)
def __repr__(self):
return f"User('{self.username}')"
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())
content = db.Column(db.Text, nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
comments = db.relationship("Comment", backref="post", cascade="all, delete-orphan", lazy=True)
def __repr__(self):
return f"Post('{self.title}', '{self.date_posted}')"
class Comment(db.Model):
id = db.Column(db.Integer, primary_key=True)
body = db.Column(db.String(100), nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), nullable=False)
post_id = db.Column(db.Integer, db.ForeignKey('post.id'), nullable=False)
def __repr__(self):
return f"Comment('{self.body}')"
In the delete_comment
function, when you are redirecting to the post
function, you have to pass the post_id
also.
It should be something like this:
return redirect(url_for('post', post_id=post.id))
For this to work you have to fetch the post id from the database.