【问题标题】:Why does this Google App Engine ndb ancestor query not work?为什么这个 Google App Engine ndb 祖先查询不起作用?
【发布时间】:2013-12-21 20:09:04
【问题描述】:

我有一个简单的 wiki 网络应用程序。如果该主题没有页面,它允许登录的用户编辑现有主题或创建新内容。我一直在努力创建一个版本历史页面,该页面列出了主题的最后 n 次编辑以及日期/编辑器。但是,我终于成功地在历史页面上显示了一个主题的 n 个以前版本的列表。我的问题不完全是为什么我现在正在做的事情......但为什么我之前尝试的事情不起作用。

这是“历史”页面的处理程序类。它的 get 方法以 '/topic' 的形式将主题作为 arg 接收:

class History(Main):
    """ Display previous versions of a topic if they exist """

    def get(self, topic):
        topic = topic[1:]
        history = Version.get_topic_history(topic).fetch(10)
        if history:
            self.render('history.html', history=history, topic=topic)
        else:
            self.redirect('/%s' % topic)

这是存储所有主题编辑的模型。它有一个classmethodget_topic_history。它按主题名称查询所有实体的版本类,然后按创建日期排序返回它们。这行得通。但是,您可以在注释掉的那条线上方看到,这是我最初所做的,但没有奏效。在第一行注释掉的行中,我检索了所有具有包含特定主题名称的祖先路径的实体的键(我认为这称为祖先查询,至少,这是我理解它正在做的事情)。然后我按祖先路径返回查询,并按创建日期/时间排序。 如您所见,此方法是从历史处理程序调用的。这对我来说,看起来它应该返回与我当前方法相同的结果,但它什么也没返回。谁能告诉我为什么?并提前感谢所有答案。

class Version(ndb.Model):
    """ wiki version history """

    created = ndb.DateTimeProperty(auto_now_add=True)
    author = ndb.StringProperty(required=True)
    topic = ndb.StringProperty(required=True)
    content = ndb.TextProperty(required=True)

    @classmethod
    def get_topic_history(cls, topic):
        # key = ndb.Key(cls, topic, parent=version_key())
        # return cls.query(ancestor=key).order(-cls.created)
        return cls.query(cls.topic == topic).order(-cls.created)

这是我存储版本的方式:

version = Version(topic=topic,
                  content=content,
                  author=User.get_user_name(self.user_id()),
                  parent=version_key())
version.put()

上面代码中分配父键的版本键函数在任何类之外:

def version_key():
    return ndb.Key('Group', 'version_group')

最后是history.html 模板示例。我正在使用 Jinja2:

{% extends "base.html" %}
{% block content %}

Topic edit history :: {{topic}}

<div>
    {% for version in history %}
    <div>
        {{version.content}}<br>
        {{version.created}} - {{version.author}}

        <a href="version/{{topic}}">view</a>
    </div> 
    {% endfor %}
</div> 
{% endblock %}

【问题讨论】:

  • 显而易见的问题,version_key() 在执行 put 时返回什么。您是否检查过您在祖先查询中使用的键实际上与您存储在 Version 实体中的父键匹配?
  • 为什么投反对票?请至少发表评论,因为您的反对意见无助于改善这篇文章,否则

标签: python google-app-engine google-cloud-datastore jinja2 webapp2


【解决方案1】:

当您创建版本实体时,父实体是version_key()

当您发出祖先查询时,祖先也应该是version_key()。但是,您查询的是祖先ndb.Key(cls, topic, parent=version_key())

我相信你想做的是:

cls.query(ancestor=version_key()).filter(topic=topic).order(-cls.created)

顺便说一句,拥有一个祖先将不利于您未来创建Version 实体的性能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-27
    • 2013-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-02
    相关资源
    最近更新 更多