GAE/Django模板(0.96)获取GqlQuery长度的过滤器
我把带有评论的查询传给我的模板:
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 个回答
我不太确定你想要实现什么,但你可能会从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变量作为标准来过滤你的查询对象。
如果你想了解更多,我在我的博客上有更详细的介绍。
你可以在你的 GqlQuery
对象上使用 count 方法来计算数量,但 GqlQuery
不允许你添加 where
这样的条件语句——要做到这一点,你需要使用 Query 和它的 filter 方法。
是的,把过滤这样的业务逻辑放到视图逻辑(也就是模板)里是非常不寻常的。通常情况下,服务器端的 Python 代码会处理这些调用,并把结果放到上下文中,这样视图逻辑(模板)就只需要处理展示的问题——服务器端决定显示什么,视图逻辑只决定 怎么 显示。
如果你更喜欢在模板中放很多逻辑的风格(这种架构很多人觉得很奇怪),可以考虑使用其他模板系统,比如 Mako,因为 Django 的模板系统其实是专门设计来 反对 这种“奇怪架构”的;-)。
在把查询结果传给模板之前,先对查询调用 .fetch() 方法,这样可以得到一个结果列表。如果你用其他方法,比如 .count(),就会导致查询被执行多次,这样会浪费计算机的处理能力和时间。
同样,如果你需要对查询结果进行筛选,最好在自己的代码里处理好这些筛选,然后再把结果传给模板系统。