【问题标题】:Google App Engine: Retrieving data from databaseGoogle App Engine:从数据库中检索数据
【发布时间】:2013-11-13 13:16:00
【问题描述】:

我正在尝试构建一个简单的博客应用程序,以使用我目前从 Udacity 学到的技能。但是,我无法从数据库中检索数据并将其显示给用户。现在,我的博客有一个永久链接,它显示用户刚刚提交的帖子,还有一个主博客页面,它将按降序显示最新的 10 个帖子。但是当我提交帖子时,帖子已成功存储在数据库中,并且我被重定向到永久链接。但是,我得到的只是一个空白页面,而不是我刚刚提交的帖子。

另外,当我回到我的主博客页面时,我看到的是这个而不是用户提交的所有帖子:

这是主要的python代码:

import os
import re
import webapp2
import jinja2
from string import letters
from google.appengine.ext import db

template_dir = os.path.join(os.path.dirname(__file__), 'templates')
jinja_env = jinja2.Environment(loader = jinja2.FileSystemLoader(template_dir),     autoescape=True)

def render_str(template, **params):
    t = jinja_env.get_template(template)
    return t.render(params)

class Handler(webapp2.RequestHandler):
    def write(self, *a, **kw):
        self.response.out.write(*a, **kw)

    def render_str(self, template, **params):
        return render_str(template, **params)

    def render(self, template, **kw):
        self.write(self.render_str(template, **kw))

def render_post(response, post):
    response.out.write('<b>' + post.subject + '</b><br>')
    response.out.write(post.content)

def post_key(name = "dad"):
    return db.Key.from_path('blog', name)

class Blogger(db.Model):
    name = db.StringProperty()
    content = db.TextProperty()
    created = db.DateTimeProperty(auto_now_add = True)

    def render(self):
        self._render_text = self.content.replace('\n', '<br>')
        return render_str("post.html", p = self)

class MainPage(Handler):
    def get(self):
        self.response.write("Visit our blog")

class BlogHandler(Handler):
    def get(self):
        posts = db.GqlQuery("SELECT * FROM Blogger order by created desc")
        self.render("frontblog.html", posts = posts)    

class SubmitHandler(Handler):
    def get(self):
        self.render("temp.html")    
    def post(self):
        name = self.request.get("name")
        content = self.request.get("content")
        if name and content:
            a = Blogger(parent = post_key(), name = name, content = content)
            a.put()
            self.redirect('/blog/%s' % str(a.key().id()))
        else:
            error = "Fill in both the columns!"
            self.render("temp.html", name = name, content = content, error = error)        

class DisplayPost(Handler):
    def get(self, post_id):
        post_id = self.request.get("post_id")
        if post_id:
            po = Blogger.get_by_id(int(post_id), parent = post_key())
            if po:
                self.render("perma.html", po = po)   
            self.response.write("No")  


app = webapp2.WSGIApplication([('/', MainPage),
                          ('/blog', BlogHandler), 
                          ('/blog/submit', SubmitHandler),
                          (r'/blog/<post_id:([0-9]+)>', DisplayPost)], debug=True)

这是所有 HTML 页面的基础 HTML 代码:

<!DOCTYPE html>
<html>
<head>
  <link type="text/css" rel="stylesheet" href="/static/main.css" />

  <title>CS 253 Blog</title>
</head>

<body>
  <a href="/blog" class="main-title">
    CS 253 Blog
  </a>

  <div id="content">
  {% block content %}
  {% endblock %}
  </div>
</body>

</html>

这是永久链接页面的 HTML 代码:

{% extends "base.html" %}

{% block content %}
  {{po.render() | safe}}
{% endblock %}

博客前面的HTML代码:

{% extends "base.html" %}

{% block content %}

  {% for p in posts %}
    {{ p.render() | safe }}
    <br><br>
  {% endfor %}

{% endblock %}

我已经为此苦苦挣扎了两天多。我在日志中也看不到任何错误。似乎是什么问题?


编辑:

根据以下答案编辑了源代码。但是,我仍然收到 404 错误。

【问题讨论】:

  • 并非如此。代码不同。此外,这里的问题与我在那篇文章中提到的代码完全不同。这里的问题似乎与从数据库中检索条目有关。否则代码运行良好,没有任何错误。

标签: python html google-app-engine web-applications blogs


【解决方案1】:

您正在使用未指定的父键创建 Blogger 实体,当您尝试在 DisplayPost 中检索您的帖子时未指定。

实体的密钥由多个部分组成。它是 Kind ("Blogger"),它是 ID (int(post_id)),也是它的祖先或父代。

因为您使用以下方式创建实体:

a = Blogger(parent = post_key(), name = name, content = content)

调用get_by_id()see the get_by_id() docs)时需要指定同一个父级。

你的解决办法是改变

po = Blogger.get_by_id(int(post_id))

po = Blogger.get_by_id(int(post_id), parent=post_key())

稍后,如果您更改博客的名称(查看 post_key() 的代码),则需要将其作为参数传递给帖子显示机制。 (例如,您可以使用子域作为博客的“名称”)。


这是解决正则表达式 URL 映射问题的先前答案:

在您的WSGIApplication 定义中,您有('/blog/([0-9]+)', DisplayPost)], debug=True)

您在 url 字符串之前缺少r,以将字符串标识为正则表达式

(r'/blog/([0-9]+), ....

您还可以选择更详细地使用参数命名

(r'/blog/&lt;post_id:([0-9]+)&gt;, ....

参考:http://webapp-improved.appspot.com/guide/routing.html

【讨论】:

  • 顺便提一下,[0-9] 的正则表达式也可以是 \d
  • 进行了必要的更改。但是,当我提交帖子并被重定向到永久链接时,我现在收到 404 错误。我已将上面修改后的代码包含在已编辑的部分下。
  • 从你的代码来看,我在你的正则表达式中看到了一个缺失的&gt;r'/blog/&lt;post_id:([0-9]+)'r'/blog/&lt;post_id:([0-9]+)&gt;'
  • 404 资源未再次找到!
  • @ManasChaturvedi 我明白为什么了,我已经更新了帖子以包含有关缺少父键的问题。对不起,我花了这么长时间才赶上! (:
猜你喜欢
  • 1970-01-01
  • 2014-04-20
  • 2016-10-19
  • 1970-01-01
  • 2011-07-03
  • 2010-10-16
  • 2011-06-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多