Google App Engine中的友好URL
我正在尝试在 Google App Engine 和 Python 中建立一个友好的 URL 查找方法。有没有人做过这个?
我已经让它工作了,但感觉非常不稳定。它的工作原理是这样的:它会把路径(比如说 /foo/bar/)拆分成一个列表。然后取列表中的最后一个元素,去数据库查询是否有匹配的记录。现在问题来了。
如果有多个 'bar',因为可能在不同的页面下都有一个 'bar',那我们怎么区分它们呢?目前我的解决方案是遍历 'bar' 的结果,然后查看它的父页面的引用属性。可是,父页面 'foo' 也可能出现多次,所以我们还得遍历这个。这很容易让人看到,可能会导致很多的循环。
更糟糕的是,一个页面可能支持多种语言,而 URL 需要与给定的语言匹配。
我现在的数据存储设置是这样的:
## Class to store pages.
class Pages(db.Model):
name = db.StringProperty()
## Some more properties for storing content
parentKey = db.SelfReferenceProperty()
## Class to store friendly url path segments
class UrlProvider(db.Model):
name = db.StringProperty()
path = db.StringProperty()
langCode = db.StringProperty()
page = db.ReferenceProperty(Pages)
然后使用友好的 URL 获取页面:
pageFromUrl = UrlProvider.gql('WHERE path = :path AND langCode = :lang', path = path, lang = templateObject.lang).fetch(100)
for pageUrl in pageFromUrl:
parentFromUrl = UrlProvider.gql('WHERE page = :page AND langCode = :lang', page = pageUrl.page.parentKey, lang = templateObject.lang).fetch(100)
for parentUrl in parentFromUrl:
if parentUrl.path == templateObject.path[-2]:
templateObject.url = parentUrl.path + '/' + path
page = pageUrl.page
它的作用是,从 UrlProvider 中获取与 templateObject.path 列表中最后一个项目匹配的所有内容。然后遍历这些内容,获取所有父页面并尝试匹配。
目前它只适用于一个根页面和一个子页面。我不知道怎么让它更动态,支持多个层级。
有没有人写过自己的方法,或者有什么好的建议?
2 个回答
这是不是你想要的? http://code.google.com/appengine/docs/python/tools/webapp/running.html#URL_Mappings
你可以用 http://test.com/browse/book/A209 代替 http://test.com/browse?category=book&productid=A209
class BrowseHandler(webapp.RequestHandler):
def get(self, category, product_id):
# Display product with given ID in the given category.
# Map URLs like /browse/(category)/(product_id) to BrowseHandler.
application = webapp.WSGIApplication([(r'/browse/(.*)/(.*)', BrowseHandler)
],
debug=True)
def main():
run_wsgi_app(application)
if __name__ == '__main__':
main()
http://code.google.com/appengine/docs/python/tools/webapp/running.html#URL_Mappings
看看里面关于“URL映射”的那一部分
这段代码是完整的,但我希望你能明白其中的意思
这是我的请求处理器,parama是我的第一个参数,paramb是我的第二个参数
class testPath(webapp.RequestHandler):
def get(self,parama,paramb): # 注意这里有两个额外的参数,不只是self
self.response.out.write(parama)
self.response.out.write(paramb)
.... # 下面你可以看到我把任何请求"/test//"都映射了,注意'r'在'urlmapping'前面
application = webapp.WSGIApplication([
(r'/test/(.)/(.)', testPath),
('/logout', LogoutHandler)
],
debug=True)
所以当我访问'myapp.com/test/fruits/green'时
parama = fruit
paramb = green
:D