源码网商城,靠谱的源码在线交易网站 我的订单 购物车 帮助

源码网商城

tornado框架blog模块分析与使用

  • 时间:2022-06-24 22:17 编辑: 来源: 阅读:
  • 扫一扫,手机访问
摘要:tornado框架blog模块分析与使用
[u]复制代码[/u] 代码如下:
#!/usr/bin/env python # # Copyright 2009 Facebook # # Licensed under the Apache License, Version 2.0 (the "License"); you may # not use this file except in compliance with the License. You may obtain # a copy of the License at # #     http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the # License for the specific language governing permissions and limitations # under the License. import markdown import os.path import re import torndb import tornado.auth import tornado.httpserver import tornado.ioloop import tornado.options import tornado.web import unicodedata from tornado.options import define, options #定义一些通用的配置信息,比如数据库的连接信息,端口信息 define("port", default=8888, help="run on the given port", type=int) define("mysql_host", default="127.0.0.1:3306", help="blog database host") define("mysql_database", default="blog", help="blog database name") define("mysql_user", default="root", help="blog database user") define("mysql_password", default="sa123", help="blog database password") #定义Application信息,它是继承tornado.web.Application 的 class Application(tornado.web.Application):    # __init__ 函数自动调用     def __init__(self):       #这里就是url对应的控制器,下面分别对应一个类,来处理里面的逻辑         handlers = [             (r"/", HomeHandler),             (r"/archive", ArchiveHandler),             (r"/feed", FeedHandler),             (r"/entry/([^/]+)", EntryHandler),             (r"/compose", ComposeHandler),             (r"/auth/login", AuthLoginHandler),             (r"/auth/logout", AuthLogoutHandler),         ]       #设置,如博客标题,模板目录,静态文件目录,xsrf,是否调试         settings = dict(             blog_title=u"Tornado Blog",             template_path=os.path.join(os.path.dirname(__file__), "templates"),             static_path=os.path.join(os.path.dirname(__file__), "static"),             ui_modules={"Entry": EntryModule},             xsrf_cookies=True,             cookie_secret="__TODO:_GENERATE_YOUR_OWN_RANDOM_VALUE_HERE__",             login_url="/auth/login",             debug=True,         )        #然后调用tornado.web.Application类的__init__函数加载进来         tornado.web.Application.__init__(self, handlers, **settings)         # Have one global connection to the blog DB across all handlers        #数据库连接信息         self.db = torndb.Connection(             host=options.mysql_host, database=options.mysql_database,             user=options.mysql_user, password=options.mysql_password) #基类,继承自tornado.web.RequestHandler 的,后面的类都是继承这个类的 class BaseHandler(tornado.web.RequestHandler):   #属性装饰器,使db函数变成一个属性,便于后面直接使用     @property     def db(self):         return self.application.db   #获得当前的用户     def get_current_user(self):         user_id = self.get_secure_cookie("blogdemo_user")         if not user_id: return None         return self.db.get("SELECT * FROM authors WHERE id = %s", int(user_id)) #首页 class HomeHandler(BaseHandler):     def get(self):      #query 查询很多列         entries = self.db.query("SELECT * FROM entries ORDER BY published "                                 "DESC LIMIT 5")         if not entries:          #redirect 重定向到一个url             self.redirect("/compose")             return      #render 渲染一个模板,后面是参数         self.render("home.html", entries=entries) class EntryHandler(BaseHandler):     def get(self, slug):     #get 得到一个值         entry = self.db.get("SELECT * FROM entries WHERE slug = %s", slug)     #raise 触发一个错误信息,后面必须接类型         if not entry: raise tornado.web.HTTPError(404)         self.render("entry.html", entry=entry) class ArchiveHandler(BaseHandler):     def get(self):         entries = self.db.query("SELECT * FROM entries ORDER BY published "                                 "DESC")         self.render("archive.html", entries=entries) class FeedHandler(BaseHandler):     def get(self):         entries = self.db.query("SELECT * FROM entries ORDER BY published "                                 "DESC LIMIT 10")         self.set_header("Content-Type", "application/atom+xml")         self.render("feed.xml", entries=entries) class ComposeHandler(BaseHandler):     #装饰器     @tornado.web.authenticated     def get(self):         id = self.get_argument("id", None)         entry = None         if id:             entry = self.db.get("SELECT * FROM entries WHERE id = %s", int(id))         self.render("compose.html", entry=entry)     @tornado.web.authenticated     def post(self):         id = self.get_argument("id", None)         title = self.get_argument("title")         text = self.get_argument("markdown")         html = markdown.markdown(text)         if id:             entry = self.db.get("SELECT * FROM entries WHERE id = %s", int(id))             if not entry: raise tornado.web.HTTPError(404)             slug = entry.slug           #execute是执行的意思             self.db.execute(                 "UPDATE entries SET title = %s, markdown = %s, html = %s "                 "WHERE id = %s", title, text, html, int(id))         else:             slug = unicodedata.normalize("NFKD", title).encode(                 "ascii", "ignore")             slug = re.sub(r"[^\w]+", " ", slug)             slug = "-".join(slug.lower().strip().split())             if not slug: slug = "entry"             while True:                 e = self.db.get("SELECT * FROM entries WHERE slug = %s", slug)                 if not e: break                 slug += "-2"             self.db.execute(                 "INSERT INTO entries (author_id,title,slug,markdown,html,"                 "published) VALUES (%s,%s,%s,%s,%s,UTC_TIMESTAMP())",                 self.current_user.id, title, slug, text, html)         self.redirect("/entry/" + slug) class AuthLoginHandler(BaseHandler, tornado.auth.GoogleMixin):     @tornado.web.asynchronous     def get(self):         if self.get_argument("openid.mode", None):             self.get_authenticated_user(self.async_callback(self._on_auth))             return         self.authenticate_redirect()   #这里定义一个函数,来供上面调用     def _on_auth(self, user):         if not user:             raise tornado.web.HTTPError(500, "Google auth failed")         author = self.db.get("SELECT * FROM authors WHERE email = %s",                              user["email"])         if not author:             # Auto-create first author             any_author = self.db.get("SELECT * FROM authors LIMIT 1")             if not any_author:                 author_id = self.db.execute(                     "INSERT INTO authors (email,name) VALUES (%s,%s)",                     user["email"], user["name"])             else:                 self.redirect("/")                 return         else:             author_id = author["id"]         self.set_secure_cookie("blogdemo_user", str(author_id))         self.redirect(self.get_argument("next", "/")) class AuthLogoutHandler(BaseHandler):     def get(self):         self.clear_cookie("blogdemo_user")       #get_argument为获得next参数的值,默认为"/"         self.redirect(self.get_argument("next", "/")) class EntryModule(tornado.web.UIModule):     def render(self, entry):         return self.render_string("modules/entry.html", entry=entry) #入口函数 def main():     tornado.options.parse_command_line()    #创建一个服务器     http_server = tornado.httpserver.HTTPServer(Application())    #监听端口     http_server.listen(options.port)   #启动服务     tornado.ioloop.IOLoop.instance().start() #调用的入口 if __name__ == "__main__":     main()
最后总结一下: 1)tornado框架中提供的几个demo,都是以这种形式来创建一个应用的 2)对每一个控制器函数,要么是,只可能有2个对外的函数,一个是get,一个是post 3)数据库有3中调用方式,query,get,exec 4)获取参数的值使用 get_argument 函数 5)重定向用redirect 函数 6)所有的函数都是属性这个类的,所有都用self调用 7)渲染模板用render函数
  • 全部评论(0)
联系客服
客服电话:
400-000-3129
微信版

扫一扫进微信版
返回顶部