我正在使用 Google AppEngine (Python) 进行小项目,由 Udacity 辅导。我无法将用户评论呈现到主页

I am working on small project with Google AppEngine (Python), tutored by Udacity. I am unable to render user comments to main page

我想将表单添加到我的 HTML 以允许用户添加数据(对我的页面的评论)并通过 GAE-Datastore 存储数据。我已经能够存储数据,但无法将用户评论发布到主页。

单独的代码文件:

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(测试评论功能的摘录)

<!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 %}

您对变量的命名方式感到困惑。您将评论列表作为 "comment" 发送到模板,然后使用 "content" 对每个项目进行迭代,然后恢复为使用 "comment"。

你应该给你的东西起一个符合逻辑的名字来反映它们是什么。在您的处理程序中:

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

并在您的模板中:

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