I am suppose to add forms to my HTML to allow users to add data (comments to my page) and also store the data via GAE-Datastore. I have been able to store the data but not able to get the user comments posted to the main page.

Seperate code files:

index.yaml

indexes:
- kind: Section
  ancestor: yes
  properties:
- name: date
  direction: desc

app.yaml

application: addnotes
version: 1
runtime: python27
api_version: 1
threadsafe: true

# [START handlers]
handlers:
- url: /stylesheets
  static_dir: stylesheets

- url: /.*
  script: addnotes.app  
# [END handlers]

# [START libraries]
libraries:
- name: webapp2
  version: latest
- name: jinja2
  version: latest  
# [END libraries]

addnotes.py

import os
import urllib`

from google.appengine.api import users
from google.appengine.ext import ndb

import jinja2
import webapp2

JINJA_ENVIRONMENT = jinja2.Environment(
    loader=jinja2.FileSystemLoader(os.path.dirname(__file__)),
    extensions=['jinja2.ext.autoescape'],
    autoescape=True)`

DEFAULT_SECTION_NAME = 'General_Submission'

# We set a parent key on the 'Comment' to ensure that they are all  
# in the same entity group. Queries across the single entity group  
# will be consistent.  However, the write rate should be limited to
# ~1/second.  

def section_key(section_name=DEFAULT_SECTION_NAME):
    """Constructs a Datastore key for a Section entity.

    We use section_name as the key.
    """
    return ndb.Key('Section', section_name)`

# [START comment]
# These are the objects that will represent our Author and our Post. We're using
# Object Oriented Programming to create objects in order to put them in Google's
# Database. These objects inherit Googles ndb.Model class.

class Author(ndb.Model):
  """Sub model for representing an author."""
  identity = ndb.StringProperty(indexed=True)
  email = ndb.StringProperty(indexed=False)

class Comment(ndb.Model):
"""A main model for representing an individual Guestbook entry."""
author = ndb.StructuredProperty(Author)
content = ndb.StringProperty(indexed=False)
date = ndb.DateTimeProperty(auto_now_add=True)

# [END comment]

class Handler(webapp2.RequestHandler): 
    """
    Basic Handler; will be inherited by more specific path Handlers
    """
    def write(self, *a, **kw):
        "Write small strings to the website"
        self.response.out.write(*a, **kw)  

    def render_str(self, template, **params):  
        "Render jija2 templates"
        t = JINJA_ENVIRONMENT.get_template(template)
        return t.render(params)   

    def render(self, template, **kw):
        "Write the jinja template to the website"
        self.write(self.render_str(template, **kw))

# [START main_page]
class MainPage(webapp2.RequestHandler):
    def get(self):
        section_name = self.request.get('section_name', DEFAULT_SECTION_NAME)
        if section_name == DEFAULT_SECTION_NAME.lower(): section_name = DEFAULT_SECTION_NAME

        comments_query = Comment.query(ancestor=section_key(section_name)).order(-Comment.date)

        comment = comments_query.fetch(10)

        # If a person is logged in to Google's Services
        user = users.get_current_user()
        if user:
            url = users.create_logout_url(self.request.uri)
            url_linktext = 'Logout'
        else:
            user = 'Anonymous Poster'
            url = users.create_login_url(self.request.uri)
            url_linktext = 'Login'

        template_values = {
            'user': user,
            'comment': comment,
            'section_name': urllib.quote_plus(section_name),
            'url': url,
            'url_linktext': url_linktext,
         }

         template = JINJA_ENVIRONMENT.get_template('notes.html')
         self.response.write(template.render(template_values))

# [END main_page]

# [START Comment Submission]
class Section(webapp2.RequestHandler):
    def post(self):
        # We set a parent key on the 'Comment' to ensure that they are all
        # in the same entity group. Queries across the single entity group
        # will be consistent.  However, the write rate should be limited to
        # ~1/second. 
        section_name = self.request.get('section_name', DEFAULT_SECTION_NAME)

        comment = Comment(parent=section_key(section_name))

        if users.get_current_user():
            comment.author = Author(
                identity=users.get_current_user().user_id(),
                email=users.get_current_user().email())

        # Get the content from our request parameters, in this case, the message
        # is in the parameter 'content'
        comment.content = self.request.get('content')

        # Write to the Google Database
        comment.put()

        query_params = {'section_name': section_name}
        self.redirect('/?' + urllib.urlencode(query_params))

#[END Comment Submission]


app = webapp2.WSGIApplication([
    ('/', MainPage), 
    ('/section', Section),
], debug=True)

notes.html (an excerpt to test out comment functionality)

<!DOCTYPE html>
{% autoescape true %}
<html>
  <head>
    <meta charset="UTF-8">
    <title>Project Stage 4</title>
  </head>
  <body>
   <h3>User Comments</h3>
   <div>
       <a href="{{ url|safe }}">{{ url_linktext }}</a>

       <form>Section Title:
          <input value="{{ section_name }}" name="section_name">
          <input type="submit" value="switch">
       </form>
       <br><br>

       <form action="/section?section_name={{ section_name }}" method="post">
          <div>
             <label>Comment: <textarea name="content" rows="5" cols="60"></textarea></label>
          </div>
          <input type="submit" value="Submit Comment">
       </form>
       <hr>

       {% for content in comment %}
           {% if comment.content %}
               <b>{{ comment.author.email }}
               {% if user and user.user_id() == comment.author.identity %}
                  (You)
               {% endif %}
               </b> wrote:
           {% else %}
               An anonymous person wrote:
           {% endif %}
           <blockquote>{{ comment.content }}</blockquote>
       {% endfor %}
   </div>
  </body>
</html>
{% endautoescape %}
1

There are 1 answers

0
Daniel Roseman On BEST ANSWER

You've confused yourself with the way you've named your variables. You send the list of comments to the template as "comment", then iterate through that using "content" for each item, but then revert back to using "comment" instead.

You should give your things logical names that reflects what they are. In your handler:

comments_query = Comment.query(ancestor=section_key(section_name)).order(-Comment.date)
comments = comments_query.fetch(10)
...
template_values = {
    ...
    'comments': comments,
    ...
 }

and in your template:

{% for comment in comments %}
   {% if comment.content %}
       <b>{{ comment.author.email }}
       ...