使用tornado和angularjs搭建网站
从这篇博文开始,将讲述建立一个站点的全过程。一方面自己从未做过这类事情,算是对自己的一个挑战,另一方面也给想要学这个的同胞留点参考,特别是*需要课程设计作业和毕业设计的同志们*。
首先介绍一下网站功能。这次要建立的一个网站类似于一个在线的辩论场,用户可以发起辩论,自由选择题目,邀请其他用户参加。参加辩论的用户可以自由选择自己论点,分正反双方辩论,当然也可以选择中立进行搅浑水。
关于要用到的技术。后端采用Python开发,框架选用Tornado,前端使用AngularJS配合jQuery,数据库选择PostgreSQL,操作系统当然要用Ubuntu了。
这里选择的技术完全是因为个人喜好,绝不是因为和其他方案相比有啥优劣之分。另外,因为我也使用过Python、JavaScript,但从未做过实际的项目,所以代码质量可能会比较丢人。
### 关于Tornado ###
Tornado是一个使用Python开发的web框架,按其作者说法,Tornado从另一个小巧的框架web.py借鉴了很多东西。和其他框架不同,Tornado并不是很庞大的一个框架,只是提供了一些基本的功能,带来的好处是比较灵活,和其他功能模块可以很容易结合到一块,缺点则是工作量多点。
##### Tornado在Ubuntu下的安装 ####
首先安装pip
sudo apt-get install python-pip
然后安装Tornado
sudo pip install tornado
当然,也可以使用easy_install来安装。
#### Tornado入门 ####
先来看一个简单的Tornado例子(代码来自tornado官网)
import tornado.ioloop
import tornado.web
class MainHandler(tornado.web.RequestHandler):
def get(self):
self.write("Hello, world")
application = tornado.web.Application([
(r"/", MainHandler),
])
if __name__ == "__main__":
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
用tornado开发web应用还是比较简单的,主要步骤就是如上所示,设置好(URL, Handler)的映射,至于其他功能,还有待进一步学习。
### 关于AngularJS ###
AngularJS是从大Google出来的前端框架,提供了数据绑定等功能,但是没有对DOM操作进行封装,所以和jQuery代培使用比较好。
### 关于PostgreSQL ###
PostgreSQL是一个开源的关系型数据库,功能强大,但是国内的普及度不高,自从9.2开始原声支持json之后,再加上本身又提供类似按列存储的功能,国外有些人已经开始把它当作NoSQL来用了。
这系列博文中即将建立的站点称为“嘚啵嘚”。
## 数据库表的设计 ##
"嘚啵嘚"使用的数据库是PostgreSQL,因此你要确定自己的系统中已经安装好了它。网上关于这方面的文章很多,不再说了。
#### 首先建立开发者账户,数据库 ####
create role developer with password 'developer';
alter role developer LOGIN;
create database debate;
grant all privileges on database debate to developer;
#### 接下来建立三个表,users用于存储用户信息,debates用于存储辩论自身的相关信息,arguments用于存储用户的论点(也就是发言内容)。 ####
建立用户信息表,这里我们只需要存储用户的帐号(使用email地址,需要保证唯一)、密码以及账户状态,同时要对每一个用户生成一个独立的ID,并在此ID上建立主键约束。
CREATE TABLE users
(
user_id serial NOT NULL, -- 用户ID
email character(256) NOT NULL, -- 用户邮箱地址
passwd character(128) NOT NULL, -- 用户密码
state smallint NOT NULL DEFAULT 0, -- 账户状态:0--未激活 1--已激活
CONSTRAINT users_pk_id PRIMARY KEY (user_id),
CONSTRAINT user_uk_email UNIQUE (email)
)
WITH (
OIDS=FALSE
);
ALTER TABLE users
OWNER TO developer;
COMMENT ON TABLE users
IS '用户信息表';
COMMENT ON COLUMN users.user_id IS '用户ID';
COMMENT ON COLUMN users.email IS '用户邮箱地址';
COMMENT ON COLUMN users.passwd IS '用户密码';
COMMENT ON COLUMN users.state IS '账户状态:0--未激活 1--已激活';
建立辩论表。
CREATE TABLE debates
(
debate_id serial NOT NULL, -- 辩论题目ID
originator serial NOT NULL, -- 发起人ID
create_time date NOT NULL DEFAULT now(), -- 发起时间
supportors_count integer NOT NULL DEFAULT 0, -- 支持者人数
opposers_count integer NOT NULL DEFAULT 0, -- 反对者人数
neutral_count integer NOT NULL DEFAULT 0, -- 中立者人数
topic character(1024) NOT NULL, -- 辩论主题
support_argument character(1024) NOT NULL, -- 正方观点综述
oppose_argument character(1024) NOT NULL, -- 反方观点综述
CONSTRAINT debate_pk_id PRIMARY KEY (debate_id),
CONSTRAINT debate_fk_originator FOREIGN KEY (originator)
REFERENCES users (user_id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
OIDS=FALSE
);
ALTER TABLE debates
OWNER TO developer;
COMMENT ON COLUMN debates.debate_id IS '辩论题目ID';
COMMENT ON COLUMN debates.originator IS '发起人ID';
COMMENT ON COLUMN debates.create_time IS '发起时间';
COMMENT ON COLUMN debates.supportors_count IS '支持者人数';
COMMENT ON COLUMN debates.opposers_count IS '反对者人数';
COMMENT ON COLUMN debates.neutral_count IS '中立者人数';
COMMENT ON COLUMN debates.topic IS '辩论主题';
COMMENT ON COLUMN debates.support_argument IS '正方观点综述';
COMMENT ON COLUMN debates.oppose_argument IS ' 反方观点综述';
建立参加者观点表
CREATE TABLE arguments
(
argument_id serial NOT NULL, -- 论点ID
debater_id serial NOT NULL, -- 辩论者ID
debate_id serial NOT NULL, -- 所属辩论ID
type integer NOT NULL DEFAULT 2, -- 论点类型:0--反对 1--支持 2--中立
publish_date date NOT NULL DEFAULT now(), -- 发布时间
viewpoint character(1024) NOT NULL, -- 观点
CONSTRAINT argument_id PRIMARY KEY (argument_id),
CONSTRAINT argument_fk_debate FOREIGN KEY (debate_id)
REFERENCES debates (debate_id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION,
CONSTRAINT argument_fk_debater FOREIGN KEY (debater_id)
REFERENCES users (user_id) MATCH SIMPLE
ON UPDATE NO ACTION ON DELETE NO ACTION
)
WITH (
OIDS=FALSE
);
ALTER TABLE arguments
OWNER TO developer;
COMMENT ON COLUMN arguments.argument_id IS '论点ID';
COMMENT ON COLUMN arguments.debater_id IS '辩论者ID';
COMMENT ON COLUMN arguments.debate_id IS '所属辩论ID';
COMMENT ON COLUMN arguments.type IS '论点类型:0--反对 1--支持 2--中立';
COMMENT ON COLUMN arguments.publish_date IS '发布时间';
COMMENT ON COLUMN arguments.viewpoint IS '观点';
其实在实际开发中,表名、数据库名、索引等最好加上前缀或者后缀来作区分,向上面这样数据库叫debates,里边有个表也叫debates其实是不太好的。
## 下面讲一下Python下操作PostgreSQL用到的模块psycopg2。 ##
### 安装psycopg2和 ###
安装过程需要安装postgresql-server-dev以及python-devel
sudo apt-get install postgresql-server-dev python-devel
sudo pip install psycopg2
##### psycopg2使用实例 #####
import psycopg2
import psycopg2.extensions
import psycopg2.extras
con = psycopg2.connect(host=‘localhost’,
post=5432,
user='developer',
password='developer',
database='debate')
cursor = con.cursor(cursor_factory=psycopg2.extras.DictCursor)
cursor.execute('select * from debates where debate_id = %s;', (debate_id,))
debate = cursor.fetchone();
con.commit()
这个模块用起来还是比较方便的,值得注意的是cursor.execute中的sql语句结尾的分号不能省略,而且第二个参数必须要是序列(List或者Tuple)
## 站点页面设计 ##
由于前端使用AngularJS,所以这次打算彻底一点,作成一个单页应用,所有前端的渲染都使用js绘制。后端除了初始页面之外,提供的都是数据。
这一个系列博客的代码都放在了Github上,地址是http://github.com/JimmyChange/debate
#### 代码主文件的设计 ####
// server.py
import tornado.ioloop
import tornado.web
import handlers
setting = [
]
application = tornado.web.Application([
(r"/", handlers.HomeHandler),
(r"/login", handlers.LoginHandler),
(r"/users/([0-9]+)", handlers.UserHandler),
(r"/debates", handlers.DebatesHandler),
(r"/debates/([0-9]*)", handlers.DebateHandler),
(r"/debates/([0-9]+)/arguments", handlers.ArgumentsHandler),
(r"/debates/([0-9]+)/arguments/([0-9]*)", handlers.ArgumentHandler),
])
if __name__ == "__main__":
application.listen(8888)
tornado.ioloop.IOLoop.instance().start()
// handlers.py
......
class DebatesHandler(BaseHandler):
def get(self):
self.write("Debates Handler")
class DebateHandler(BaseHandler):
def get(self, debate_id):
self.write(debate_id)
self.write("Debate Handler")
def post(self, debate_id):
self.write(debate_id)
self.write("Debate Handler")
def put(self, debate_id):
self.write(debate_id)
self.write("Debate Handler")
def delete(self, debate_id):
self.write(debate_id)
self.write("Debate Handler")
......
上面只是代码的一部分,列在这里是为了说明一下URL的格式。对于/collections的操作都是对于整个集合的,而对于/collection/的都是针对单个项目的。
今天就折腾这些,下午打球把他妈脚扭了,得歇着。
使用tornado和angularjs搭建网站的更多相关文章
- Angular JS + Express JS入门搭建网站
3月份开始,接到了新的任务,跟UI开发有关,用的是Angular JS,Express JS等技术.于是周末顺便学习下新技术. 组里产品UI架构如下: 其中前端,主要使用Angular JS框架,另外 ...
- requirejs+angularjs搭建SPA页面应用
AngularJS诞生于2009年,由Misko Hevery 等人创建,后为Google所收购.是一款优秀的前端JS框架,已经被用于Google的多款产品当中.AngularJS有着诸多特性,最为核 ...
- 利用Columnal网格系统快速搭建网站的基本布局结构
1.下面是一些对响应式设计提供了不同程度支持的CSS框架: (1)Semantic(http://semantic.gs); (2)Skeleton(http://getskeleton.com); ...
- javaweb学习总结十七(web应用组织结构、web.xml作用以及配置虚拟主机搭建网站)
一:web应用组织结构 1:web应用组成结构 2:安装web组成机构手动创建一个web应用程序目录 a:在webapps下创建目录web b:在web目录下创建html.jsp.css.js.WEB ...
- IIS6.0服务器搭建网站无法访问解决方法
IIS6.0服务器搭建网站无法访问解决方法 IIS6.0服务器搭建网站无法访问解决方法很多朋友在用IIS6架网站的时候遇到不少问题,而这些问题有些在过去的IIS5里面就遇到过,有些是新出来的, ...
- Flask+Mysql搭建网站之数据库问题
关于 SQLAlchemy (1.0.8) 和 Flask-SQLAlchemy (2.0) SQLALchemy 是Python语言的SQL工具包及对象关系映射(ORM)工具.Flask-SQLAL ...
- Flask+Mysql搭建网站之其他笔记
写在前面 之前用过python的另外一个框架,Django.感觉Django比Flask的资料要多.做这个网站的时候,遇到一些棘手的问题,怎么百度也就只能找到翻来覆去的官方文档以及miguelgrin ...
- 利用ThinkPHP搭建网站后台架构
记录一下ThinkPHP搭建网站后台.调整好样式等操作步骤 下载好ThinkPHP(3.2.3),解压后将核心文件夹ThinkPHP以及index.php等文件复制到网站根目录如下图 对index.p ...
- PHP绿色集成环境在云服务器上的应用,PHPWAMP在服务器上搭建网站案例
问:什么叫WAMP?答:Windows下的Apache+Mysql+PHP,称之为WAMP. 本文案例采用的PHP集成环境是我自己开发的纯绿色版WAMP软件(PHPWAMP). 我在这款集成环境里集成 ...
随机推荐
- Devexpress VCL Build v2014 vol 15.2.3 发布
2016年第一个版本,继续修补. New Major Features in 15.2 What's New in VCL Products 15.2 Breaking Changes To lear ...
- 英语语法 It all started the summer before second grade when our moving van pulled into her neighborhood
It all started the summer before second grade when our moving van pulled into herneighborhood It all ...
- js 和 c# 方法互调
js访问c#代码 1 js <script type="javascript"><%=test()%></script> c# public ...
- iOS应用之微信支付集成-直接前端集成
所有信息的生成都在前端完成,包括对订单进行sign签名以及MD5签名加密(此方法相对来说有些复杂,没有官方给的方法简单).注:官方给的是v3&v4支付流程,签名和加密都是在服务器端进行,由于没 ...
- J. Bottles 二维费用背包问题
http://codeforces.com/contest/730/problem/J 3 4 36 1 90 45 40 其实可以知道,选出多少个瓶子呢?是确定的,当然选一些大的 ...
- CSS从大图片上截取小图标的操作以及三角形的画法
#name{ background:url(images/name.png) no-repeat 2px 2px; background-position: -2px -70px;//其中这个是定位图 ...
- ZT 第一范式,第二范式,第三范式
第一范式,第二范式,第三范式 Posted on 2012-05-09 16:30 GISerYang 阅读(6472) 评论(0) 编辑 收藏 第一范式 存在非主属性对码的部分依赖关系 R(A,B, ...
- 03-JAVA方法
答:我发现这两个方法的返回类型以及参数类型不一样. package 汉诺塔问题; /**汉诺塔问题*作者:徐浩军 日期:16.10.16 天气:晴*/ public class TowersOfHan ...
- zabbix使用host metadata方式主动注册
host metadata是zabbix2.2新增加的功能,该功能在zabbix-agent端可以自定义条件,在选择自动注册的时候,zabbix-server端可以根据host metadata来选择 ...
- three.js 之旅 (五)--跟场景scene相关的函数
1.scene.add(obj); 在场景中添加物体 2.scene.remove(obj); 在场景中移除物体 3.scene.children(); 获取场景中所有子对象的列表 4.sc ...