GAE/Django模板(0.96)获取GqlQuery长度的过滤器

0 投票
3 回答
604 浏览
提问于 2025-04-15 20:57

我把带有评论的查询传给我的模板:

    COMM = CommentModel.gql("ORDER BY created")

    doRender(self,CP.template,{'CP':CP,'COMM':COMM, 'authorize':authorize()})

我想输出评论的数量,所以我尝试这样做:

    <a href="...">{{ COMM|length }} comments</a>

这样并不奏效(对,因为COMM是GqlQuery,而不是一个列表)。我该怎么办呢?有没有办法把GqlQuery转换成列表,或者有没有其他解决方案?(第一个问题)[1]

第二个问题[2]是,如何在模板中过滤这个列表?有没有像这样的结构:

    <a href="...">{{ COMM|where(reference=smth)|length }} comments</a>

这样我就可以获取不仅仅是所有评论的数量,而是只获取具有特定db.ReferenceProperty()属性的评论,比如说。

最后一个问题[3]:使用模板做这样的事情是不是很奇怪?

更新:问题[1]和[3]我基本上明白了,感谢Nick Johnson和Alex Martelli。

问题[2]比较棘手,可能与MVC的理念相悖,但我真的希望只用模板来解决这个问题 :(有一些原因)。这可能会很丑陋。

3 个回答

0

我不太确定你想要实现什么,但你可能会从URL映射中受益,不过这需要一些额外的代码。基本的想法是,你可以把想要过滤的值变成一个“目录”。下面的例子会更清楚:

<a href="basepath/{{ value.tofilterfrom }}">link text</a>

然后在你的Python代码中,你需要用一个独特的处理器来修改你的WSGIApplication对象。可以这样做:

application = WSGIApplication(
                              [('/', MainPage),
                               (r'/basepath/(.*)', Products),

只需创建一个叫做Products的新类,它会自动获取过滤值并把它存储在一个变量里,像这样:

class Products(webapp.RequestHandler):
    def get(self, ProductID):

就这样,你可以根据需要扩展这个功能,增加更多的层级。在Products类中,你只需使用ProductID变量作为标准来过滤你的查询对象。

如果你想了解更多,我在我的博客上有更详细的介绍。

1

你可以在你的 GqlQuery 对象上使用 count 方法来计算数量,但 GqlQuery 不允许你添加 where 这样的条件语句——要做到这一点,你需要使用 Query 和它的 filter 方法。

是的,把过滤这样的业务逻辑放到视图逻辑(也就是模板)里是非常不寻常的。通常情况下,服务器端的 Python 代码会处理这些调用,并把结果放到上下文中,这样视图逻辑(模板)就只需要处理展示的问题——服务器端决定显示什么,视图逻辑只决定 怎么 显示。

如果你更喜欢在模板中放很多逻辑的风格(这种架构很多人觉得很奇怪),可以考虑使用其他模板系统,比如 Mako,因为 Django 的模板系统其实是专门设计来 反对 这种“奇怪架构”的;-)。

3

在把查询结果传给模板之前,先对查询调用 .fetch() 方法,这样可以得到一个结果列表。如果你用其他方法,比如 .count(),就会导致查询被执行多次,这样会浪费计算机的处理能力和时间。

同样,如果你需要对查询结果进行筛选,最好在自己的代码里处理好这些筛选,然后再把结果传给模板系统。

撰写回答