我正在使用 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 }}
...
我想将表单添加到我的 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 }}
...