How to create a blog comment system with webapp2 (on Google App Engine) – Part 1

I am developing a Q&A website. Therefore, people must be able to answer questions and this system would be the same as commenting on posts. This is going to be a little longer than other posts so I divided this post by 2 sections:

1. Creating database and storing comments.
2. Rendering comments using Jinja2

It is not a complex problem but it was a little confusing when I was first implementing the system. The basic idea is that when people are submitting question A, the comments submitted under question A must be associated with question A. Using webapp2, we can easily do this by using the Key and the id of each question. But before we dive into creating key and id, let’s first construct the data model for comments.

See the below code for an example.

class Reply(db.Model):
    content = db.TextProperty(required = True)
    question_post = db.ReferenceProperty(Post)
    created = db.DateTimeProperty(auto_now_add = True)
    last_modified = db.DateTimeProperty(auto_now = True)
    user = db.StringProperty()

The Comment class looks just like any other entity. However, I used a new property class called ReferenceProperty. This property class references to another model instance, and this allows me to fetch comments only associated to a specific post (question A). Here’s the documentation.

https://cloud.google.com/appengine/docs/python/datastore/typesandpropertyclasses#ReferenceProperty

See the below Question class that is referenced by the property “question_post”

class Question(db.Model):
    question_content = db.StringProperty(required = True)
    created = db.DateTimeProperty(auto_now_add = True)
    last_modified = db.DateTimeProperty(auto_now = True)
    user = db.StringProperty()

Now, let’s look at HTML template for receiving comments data.

<input type="submit" value="Comment">
<input type="hidden" name="question_key" value="{{ question.key() }}" />

The comments input form is located under a question. Users will be able to see comments under the question. The important part is that you have to get the key of the question by using the key() method {{ post.key() }} and the value is hidden as we just want this to be stored in our comments database.

Let’s now look at the main.py.

reply_content = self.request.get('content')

        if reply_content:
            question_key = self.request.get('question_key')
            question_post = Question.get(question_key)
            user=self.user.name

            q = Comment(content = reply_content, question_post = question_post, user = user)
            q.put()

We can use self.request.get(“question_key”) and get the comment content using self.request.get(“content”). Once you receive the data, you can now store this data into the Comment datastore. Since you have the key, the comment will be stored along with the key and this will allow us to only render comments with the id.

Keep in mind that this is based on db datastore and “ReferenceProperty” becomes “KeyProperty.” I will also write a post on ndb datastore once I complete migrating my datastore to ndb.

Leave a comment