Tornado Framework Blog Module analysis and use _python

Source: Internet
Author: User
Tags auth

Copy Code code as follows:

#!/usr/bin/env python
#
# Copyright 2009 Facebook
#
# licensed under the Apache License, Version 2.0 (the "License"); May
# not use this file except in compliance with the License. For May obtain
# A copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# unless required by applicable or agreed to in writing, software
# Distributed under the License is distributed on ' as is ' basis, without
# warranties or CONDITIONS of any KIND, either express OR implied. 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
#定义一些通用的配置信息, such as database connection information, port information
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信息, it's inherited tornado.web.Application.
Class Application (Tornado.web.Application):
# __init__ function calls automatically
def __init__ (self):
#这里就是url对应的控制器, each of these corresponds to a class that handles the logic inside.
handlers = [
(r "/", Homehandler),
(r "/archive", Archivehandler),
(r "/feed", Feedhandler),
(r "/entry/([^/]+)", Entryhandler),
(r "/compose", Composehandler),
(r "/auth/login", Authloginhandler),
(r "/auth/logout", Authlogouthandler),
]
#设置, such as blog title, template directory, static file directory, XSRF, whether debugging
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,
)
The __init__ function of the Web.application class is loaded in #然后调用tornado.
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)

#基类, inherited from Tornado.web.RequestHandler, and subsequent classes are
Class Basehandler (Tornado.web.RequestHandler) that inherit this class:
#属性装饰器, Make the DB function a property that makes it easy to use
    @property
    def db (self) directly in the following:
         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 Query many columns
         entries = self.db.query ("SELECT * from Entries ORDER by published"
                                  "DESC LIMIT 5")
         If not entries:
     #redirect Redirect to a URL
             self.redirect ("/compose")
             return
#render render a template, followed by parameters
        Self.render ("home.html", entries=entries)


Class Entryhandler (Basehandler):
def get (self, slug):
#get Get a value
Entry = Self.db.get ("SELECT * from entries WHERE slug =%s", slug)
#raise triggers an error message that must be followed by a type
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")
        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 ()
#这里定义一个函数, for the above call
def _on_auth (self, user):
If not User:
Raise Tornado.web.HTTPError ("Google auth failed")
Author = self.db.get ("select * FROM authors WHERE email =%s")
user["Email"])
If not author:
# Auto-create-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参数的值, the default is "/"
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 ()

Finally, summarize:

1 The Tornado framework provides several demos that are used in this form to create an application
2 for each controller function, or, there may be only 2 external functions, one is get, one is post
3 The database is called in 3 ways, query,get,exec
4 Get the value of the parameter using the Get_argument function
5) redirect with redirect function
6 All functions are attributes of this class, all are called with self
7) Rendering template with render function

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.