Skip to main content
 首页 » 编程设计

python之为什么这个 Google App Engine ndb 祖先查询不起作用

2025年05月04日18cyq1162

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

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

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) 

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

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 实体时,父级是 version_key()。

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

我相信你想做的是:

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

顺便说一句,只有一个祖先会对您将来创建 Version 实体的性能产生不利影响。