Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialAthoug Alsoughayer
7,949 PointsHow to add comments to post in Flask application?
I'm trying to add comments to a single post (just like a comments section in a blog) However I'm facing a problem when trying to submit the comment in the form. I would get an error back stating *Method Not Allowed * - The method is not allowed for the requested URL. I get a 405 http response.
my code is building on the build a social app project in Flask. The models.py script has an added comments calls as follow:
class Comment(Model):
timestamp = DateTimeField(default=datetime.datetime.now)
content = TextField()
user = ForeignKeyField(
rel_model=User,
related_name='comments'
)
post = ForeignKeyField(
rel_model=Post,
related_name='comments'
)
class Meta:
database = DATABASE
order_by = ('-timestamp',)
So in the view function, I grab the single post, instantiate the Comments form and added the on submit validate heres how the code looks like:
@app.route('/post')
@app.route('/post/<int:postid>')
def singlepost(postid=None):
postNumber = request.args.get('post', postid)
post = models.Post.select().where(models.Post.id == postNumber).get()
form = forms.CommentForm()
if form.validate_on_submit():
models.Comment.create(content=form.content.data.strip(), post=post._get_current_object() , user=g.user._get_current_object())
flash("Comment posted!", 'alert-success')
return redirect(url_for('singlepost'))
return render_template("singlepost.html", post=post, form=form)
I am not sure if I am creating the comment correctly or not. (Maybe my problem is with the post object to connect it to the comment since it's a foreign key) My template code is singlepost.html :
{% extends "base.html" %}
{% from 'macros.html' import render_field %}
{% block page_content %}
<article>
<h6>
Post by <a href="{{ url_for('stream', username=post.user.username)}}">
{{ post.user.name}}
</a>
<span style="float:right; clear:right; ">at {{ post.timestamp.strftime('%d-%m-%Y %H:%M')}}</span>
</h6>
<div class='post'>
<div style="width: 100%; display: inline-block;">
<h4>
<a href="{{ url_for('singlepost', post=post.id) }}">
{{ post.content}} </a>
</h4>
</div>
</div>
<hr>
</article>
<!-- comment section -->
<form class="form form-horizontal col-md-12" method="post" role="form">
{{ form.hidden_tag() }} <!-- Renders hidden fields inside of a hidden <div>. -->
{% for field in form %} <!-- it will help us loop through the elements in our forms.py -->
{{ render_field(field) }} <!-- We used the maco we created to render the feild -->
{% endfor %}
<br>
<br>
<button type='submit' class="btn btn-primary" id='submit'>Submit</button>
</form>
{% endblock %}
Can anyone point the mistake, or guide me to how to work it out? I'm new to working with databases so having some obstacles completing the task. I truly appreciate the treehouse community for their support, and help.
3 Answers
Chris Freeman
Treehouse Moderator 68,423 PointsSometime the answer is right in front of you. The HTTP 405 error:
The method specified in the Request-Line is not allowed for the resource identified by the Request-URI. The response MUST include an Allow header containing a list of valid methods for the requested resource.
You need to add the Post access method the app.route
statement:
@app.route('/post/<int:postid>', methods=('Get', 'Post'))
def singlepost(postid=None):
Athoug Alsoughayer
7,949 PointsIt's still not working. I get this error message ** PostDoesNotExist: Instance matching query does not exist: ** I think maybe because the result is a SelectQuery and not an object. Because in the user we turned it to an object so shouldn't we do that with post? I don't know I'm just thinking of possibilities. Been trying to look on how to convert a selectQuery to an object but still couldn't find a solution.
Chris Freeman
Treehouse Moderator 68,423 PointsThe .get()
at the end of the line is what returns the object instead of a query set.
Is it the Post get or the Comment create that is raising the error?
Can you post the stack trace of the error?
Athoug Alsoughayer
7,949 PointsIt's the comment create here's the error that it pops up in the http error code I get a 302, then a 404 ** UnboundLocalError UnboundLocalError: local variable 'post' referenced before assignment**
the code is look like
@app.route('/post/', methods=('Get', 'Post'))
def singlepost(postid=None):
postNumber = request.args.get('post', postid)
try:
post = models.Post.select().where(models.Post.id == postNumber).get()
except models.DoesNotExist:
# abort(404)
pass
form = forms.CommentForm()
if form.validate_on_submit():
models.Comment.create(content=form.content.data.strip(), post=post , user=g.user._get_current_object())
flash("Comment posted!", 'alert-success')
return redirect(url_for('singlepost'))
return render_template("singlepost.html", post=post, form=form)
Chris Freeman
Treehouse Moderator 68,423 PointsI don't see the app.route which shows the post ID number as a argument.
If there is no post ID as an argument then postid
is none and the try
will fail. This leaves post
undefined.
You need to add a check to be sure you have a valid post ID before trying to create the comment.
Athoug Alsoughayer
7,949 PointsOh! The problem was that I wasn't passing the post and field section so I changed the return to render template and it worked! Thank you so much Chris your guidance truly helped. Thank you so muchQ
MUZ140952 Brighton Phiri
3,207 Pointsjust do this:
@app.route('/post/<int:postid>', methods=('Get', 'Post')) def singlepost(postid=None):
Athoug Alsoughayer
7,949 PointsStill doesn't work and gives me back the same error PostDoesNotExist: Instance matching query does not exist:
Athoug Alsoughayer
7,949 PointsAthoug Alsoughayer
7,949 PointsOh my! you're right I forgot to add that. It works, however I now get the error ** AttributeError: 'Post' object has no attribute '_get_current_object'** I felt that there was something wrong with the post that I am trying to assign. I tried both post, and post._get_current_object and it still doesn't work. How do I reference the current post object just like what we did with user? again thank you so much for your help!
Chris Freeman
Treehouse Moderator 68,423 PointsChris Freeman
Treehouse Moderator 68,423 PointsIn your
singlepost
view, you already have thepost
you are looking for.... The solution should be simplePlease let me know if this solves it.