【Tornado +Tenjin+MongoDB】- 初窥Tornado

Tornado简介


Tornado是使用Python开发的全栈式(full-stack)Web框架和异步网络库,最早由Friendfeed开发。通过使用非阻塞IO,Tornado可以处理数以万计的开放连接,是long polling、WebSockets和其他需要为用户维护长连接应用的理想选择。

Tornado 跟其他主流的Web服务器框架(主要是Python框架)不同是采用epoll非阻塞IO,响应快速,可处理数千并发连接,特别适用用于实时的Web服务。

Tornado 主要分成四个部分:

  • Web 框架(包括 RequestHandler,用于创建Web程序的基类,以及各种支持类)
  • 实现 HTTP 的客户端和服务器端 (HTTPServer 和 AsyncHTTPClient).
  • 一个异步网络库 (IOLoop 和 IOStream)
  • 一个协程库(tornado.gen) ,使得异步调用代码能够以更直接的方式书写,取代回调链接

Mac下安装tornado


自动安装

可以通过 pip 或者 easy_install 来安装。例如:

sudo easy_install tornado       #安装tornado
手动安装

下载传送门:http://www.tornadoweb.cn

然后运行:

tar xvzf tornado-1.2.1.tar.gz
cd tornado-1.2.1
python setup.py build #编译安装程序
sudo python setup.py install #安装

接下来进行测试是否安装成功:

# -*- coding:utf-8 -*-

import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web

from tornado.options import define, options

define("port", default=8000, help="run on the given port", type=int)

class IndexHandler(tornado.web.RequestHandler):
    def get(self):
        greeting = self.get_argument('greeting', 'Hello')
        self.write(greeting + ', tornado!')

if __name__ == "__main__":
    tornado.options.parse_command_line()
    app = tornado.web.Application(handlers=[(r"/", IndexHandler)])
    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    tornado.ioloop.IOLoop.instance().start()

给权限后,执行./hello.py –port=1234启动服务器。

在本地浏览器打开http://localhost:1234/可以看到:
Hello, tornado!

ok,tornado环境已经搭建完成

MongoDB环境搭建(Mac)


MongoDB下载传送门:http://downloads.mongodb.org/osx/mongodb-osx-x86_64-2.6.3.tgz

解压完之后,MongoDB其实已经可以开始用了。

首先我们在mongodb目录下创建data文件夹,用来存储数据库数据。打开终端,cd到mongodb的目录中bin文件夹,运行mongod,命令如下:

./mongod --dbpath=/Users/edison/mongodb/data #mac的命令

#dbpath是数据库位置参数,这里我们使用的是刚才创建的data文件夹

大致如下:

FAQ:

–dbpath的位置权限不够,所以可能需要赋予该有的权限。

chmod -R 777 /Users/edison/mongodb/data

安装PyMongo


PyMongo 是 MongoDB 的 Python 接口开发包。我们需要安装PyMongo来获得Tornado应用使用MongoDB的能力。

自动安装:
sudo easy_install pymongo
手动安装:

下载传送门:https://pypi.python.org/pypi/pymongo/#downloads

Tenjino简介


  • 多脚本语言模板引擎 Tenjin
  • 号称全球最快的模板引擎

Tenjin 是一个超快而且轻量级的模板引擎,类似 eRuby ,但支持嵌套的布局模板、嵌入其他模板,捕获模板的某个部分等等,同时还支持文件缓存和内存缓存、预处理等。

提供多种脚本语言的版本,包括:Ruby, PHP, Perl, Python 和 JavaScript。

自动安装
sudo easy_install Tenjin
手动安装

下载传送门:https://pypi.python.org/pypi/Tenjin/

tar xzf Tenjin-X.X.X.tar.gz
cd Tenjin-X.X.X
sudo python setup.py install

使用指南:http://www.liujingze.com/docs/pytenjin/pytenjin-users-guide.html#


到这边所需要的环境都搭建完成了,开始写项目把!

手摸手教学之 来个demo


test1.py

#! /usr/bin/python
# -*- coding:utf-8 -*-
import tornado.httpserver
import tornado.ioloop
import tornado.options
import tornado.web

import time
import os.path

import tenjin
import pymongo

# 调试模式
import tornado.autoreload

from tenjin.helpers import *
from tenjin.html import *

from tornado.options import define, options
define("port", default=8000, help="run on the given port", type=int)


class IndexHandler(tornado.web.RequestHandler):
    def get(self):
        engine = tenjin.Engine(path=['view'], postfix='.html')
        table = db.mytable
        blogs = table.find().sort("_id",pymongo.DESCENDING)

        context = {
            'blogs':blogs,
            "page_title":"我的博客",
        }

        html = engine.render(':index', context)
        self.finish(html)

class BlogHandler(tornado.web.RequestHandler):
    def get(self, id=None):
        engine = tenjin.Engine(path=['view'], postfix='.html')
        table = db.mytable
        blog = table.find_one({"id": int(id)})

        context = {
            'blog':blog,
            "page_title":"我的博客",
        }

        html = engine.render(':blog', context)
        self.finish(html)


class EditHandler(tornado.web.RequestHandler):
    def get(self, id=None):
        engine = tenjin.Engine(path=['view'], postfix='.html')
        table = db.mytable

        if id:
            blog = table.find_one({"id": int(id)})

            context = {
                'blog':blog,
                'type':"edit"
            }
        else:
            context = {
                'type':"add"
            }

        html = engine.render(':edit', context)
        self.finish(html)

    def post(self, id=None):
        table = db.mytable
        blog = dict()

        if id:
            blog = table.find_one({"id": int(id)})

        blog['title'] = self.get_argument("title", None)
        blog['content'] = self.get_argument("content", None)

        if id:
            table.save(blog)
        else:
            last = table.find().sort("id",pymongo.DESCENDING).limit(1)
            lastone = dict()
            for item in last:
                lastone = item
            blog['id'] = int(lastone['id']) + 1
            blog['date'] = int(time.time())
            table.insert(blog)

        self.redirect("/")


class DelHandler(tornado.web.RequestHandler):
    def get(self, id=None):
        table = db.mytable
        if id:
            blog = table.remove({"id": int(id)})

        self.redirect("/")

db = ""

if __name__ == "__main__":
    tornado.options.parse_command_line()

    app = tornado.web.Application(
        handlers=[(r'/', IndexHandler),
                  (r"/blog/([0-9Xx\-]+)", BlogHandler),
                  (r"/edit/([0-9Xx\-]+)", EditHandler),
                  (r"/delete/([0-9Xx\-]+)", DelHandler),
                  (r"/add", EditHandler),
                  ],
        template_path=os.path.join(os.path.dirname(__file__), "templates"),
        static_path=os.path.join(os.path.dirname(__file__), "static"),
    )

    client = pymongo.MongoClient()
    db = client.test
    # print(db)

    http_server = tornado.httpserver.HTTPServer(app)
    http_server.listen(options.port)
    loop = tornado.ioloop.IOLoop.instance()

    # 调试模式 仅监听py文件的改动
    tornado.autoreload.start(loop)
    loop.start()

index.html

<?py #@ARGS blogs, page_title ?>
<!DOCTYPE html>
<html>
    <head>
        <title>${page_title}</title>
        <link rel="stylesheet" type="text/css" href="../static/css/style.css">
    </head>
    <body>
    <div class="main">
            <div class="container">
                <h1>HTSS的博客</h1>
                <?py for blog in blogs: ?>
                <div class="content">
                    <div class="Title">
                        <p>
                              ${ blog['title'] }
                        </p>
                        <p>
                              <span class="Time">${ time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(blog['date'])) ) }</span>
                        </p>
                    </div>
                    <div class="Article">
                        <p>
                            <a href="blog/${ blog['id'] }">点击阅读</a>
                        </p>
                    </div>
                </div>
                <?py #endfor ?>
                <a href="/add">
                    <input type="button" class="Article Button Submit" value="发布博客" onclick="document.location.href('/add/')"/>
                </a>
            </div>
        </div>
    </body>
    </body>
</html>

blog.html

<?py #@ARGS blog, page_title ?>
<!DOCTYPE html>
<html>
    <head>
        <title>${page_title}</title>
        <link rel="stylesheet" type="text/css" href="../static/css/style.css">
    </head>
    <body>
    <div class="main">
            <div class="container">
                <h1><a href="/">HTSS的博客</a></h1>
                <div class="content">
                    <div class="Title">
                        <p>
                            ${ blog['title'] }
                        </p>
                        <p>
                            <span class="Time">${ time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(blog['date'])) ) }</span>
                        </p>
                    </div>
                    <div class="Article">
                        <p>
                            ${ blog['content'] }
                        </p>
                    </div>
                    <div class="buttonDiv">
                        <a href="/edit/${ blog['id'] }">
                            <input type="button" class="Article Button Edit" value="编    辑"/>
                        </a>
                        <a href="/delete/${ blog['id'] }">
                            <input type="button" class="Article Button Delete" value="删    除"/>
                        </a>
                    </div>
                </div>
                </div>
            </div>
        </div>
    </body>
    </body>
</html>

edit.html

<?py #@ARGS blog, type ?>
<!DOCTYPE html>
<html>
    <head>
        <title>编辑</title>
        <link rel="stylesheet" type="text/css" href="../static/css/style.css">
    </head>
    <body>
    <div class="main">
            <div class="container">
                 <h1><a href="/">HTSS的博客</a></h1>
                <div class="content">
                    <?py if type == "edit": ?>
                    <form method="post" action="/edit/${ int(blog['id']) }">
                        <input type="hidden" name="id" value="${ int(blog['id']) }">
                    <?py else: ?>
                    <form method="post" action="/add">
                    <?py #endif ?>
                        <p>文章标题:</p>
                        <?py if type == "edit": ?>
                            <input type="text" class="Title" name="title" placeholder="在这里输入你的标题" value="${ blog.get('title', '') }" />
                        <?py else: ?>
                             <input type="text" class="Title" name="title" placeholder="在这里输入你的标题"/>
                        <?py #endif ?>
                        <p>文章正文:</p>
                        <textarea type="text" class="Article" id="myArticle" name="content" placeholder="在这里输入你的正文">
                            <?py if type == "edit": ?>
                                ${ blog.get('content', '') }
                            <?py #endif ?>
                        </textarea>
                        <br/>
                        <?py if type == "edit": ?>
                        <input type="submit" class="Article Button Submit" value="修    改"/>
                        <?py else: ?>
                        <input type="submit" class="Article Button Submit" value="发    布"/>
                        <?py #endif ?>
                    </form>
                </div>
            </div>
        </div>
    </body>
    </body>
</html>

Run!


服务器跑起来

这边我是给了port,为1234。如果不给port则是

define("port", default=8000, help="run on the given port", type=int)

此时打开浏览器,访问http://localhost:1234/,我们可以发现网站已经可以正常访问。

Handlers 和 settings
app = tornado.web.Application(
        handlers=[(r'/', IndexHandler),
                  (r"/blog/([0-9Xx\-]+)", BlogHandler),
                  (r"/edit/([0-9Xx\-]+)", EditHandler),
                  (r"/delete/([0-9Xx\-]+)", DelHandler),
                  (r"/add", EditHandler),
                  ],
        template_path=os.path.join(os.path.dirname(__file__), "templates"),
        static_path=os.path.join(os.path.dirname(__file__), "static"),
    )
  • handlers是用于设定url与处理类间的映射关系。

  • template_path用于指定我们之后要渲染的html文件的文件夹位置

  • 用于指定之后要用的的一些引用文件(如css文件、js文件、图片等)的文件夹位置

数据库
client = pymongo.MongoClient()
db = client.test

mongodb默认是没有用户名和密码的

Hello World!


class IndexHandler(tornado.web.RequestHandler):
    # 一个get请求
    def get(self):
        # 这个是tenjin模板 
        # path是要渲染的html文件的文件夹位置
        # postfix是文件后缀
        engine = tenjin.Engine(path=['view'], postfix='.html')
        # 获取表
        table = db.mytable
        #查找数据 根据_id 倒序
        blogs = table.find().sort("_id",pymongo.DESCENDING)

        context = {
            'blogs':blogs,
            "page_title":"我的博客",
        }

        html = engine.render(':index', context)
        self.finish(html)
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值