本次分享的项目信息如下
- 项目名称:web-sign
- 涉及语言:Python3 + Html5 + Css3
- 开源类型:18年生产环境项目开源
- 时间节点:18年初版开发完成,21年4月首次开源
- 仓库:Gitee.com
- 通过本项目您可以学习到:Python3的基本语法、tornado 框架的基础应用、web开发基础和架构
项目仓库地址在文章末尾,下面我们来了解一下这个简单的练手。
项目需求是实现游戏公会出征统计(18年盛行的红衣军团玩法和公会),在出征前登记所有要出征的人员信息。
我个人搭建web项目喜欢从前端页面开始,以便于确定后端的功能需求。
首先,这个页面不需要登录,仅仅需要简单的一个收集表,一个提交按钮即可。所以,我们构建一个基础的不美化的表单页面,如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>出征登记</title>
<h1 style="color: cornflowerblue">xxxx登记</h1>
</head>
<body background="xinkon.jpg" style=" background-repeat:no-repeat ;
background-size:100% 100%;background-attachment:fixed;" >
<form action="" method="post">
<p> QQ昵称<input type="text" required="required" placeholder="请输入正确的QQ昵称" name="user"></p>
<p> QQ号<input type="text" required="required" class="form-control" id="recoSoft" maxlength="11"
onkeyup="value=value.replace(/[^\d]/g,'')" placeholder="请输入正确的QQ号" style="width: 200px;" name="userid"/>
<p> 部门(参考下方选项)<input type="text" required="required" placeholder="请输入正确的部门" name="depar"></p>
红衣军总部,
红衣军一团,
红衣军二团,
红衣军三团,
<p> yy号<input type="text" required="required" placeholder="该项将作为核对的主要依据" name="yyid"></p>
<p>游戏昵称<input typr="text" required="required" placeholder="请输入正确的昵称" name="yxnc">
<p>游戏ID<input typr="text" required="required" placeholder="请输入正确的id" name="yxid">
<p style="color: cornflowerblue"><input type="submit" value="提交登记"></p>
</form>
</body>
</html>
这样我们会得到一个极简的表单页面,前端的工作就结束了,接下来我们在目录下创建Python脚本程序(.py文件)。这个项目原本是采用的flask框架。后来为了便于管理和提升性能(最后这个项目没多久就不使用了),采用了更加完善的tornado框架。
为了使用tornado框架,我们需要引入tornado库,如果您的电脑未安装该库,可以在CMD或终端通过以下命令安装tornado库:
pip install tornado
安装好后我们使用import将他引入到我们的项目中,并根据自己的需求构建基础的启动代码,下面代码的含义通过注释表达:
from tornado import web,ioloop,httpserver #tornado 框架需要
import gc #清理缓存
import time #获取时间
import socket #socket
SIGN_FILE_HANDLER = open('sign.csv', 'a')
SIGN_FILE_HANDLER.write('姓名')
SIGN_FILE_HANDLER.write('部门')
SIGN_FILE_HANDLER.write('编号\n')
SIGN_FILE_HANDLER.close()
port = input("inport post: ") #自定义端口,手动输入
int(port)
print("port is {a} are you sure?".format(a = port))
#文件句柄
SIGN_FILE_HANDLER = open('sign.csv','a') #以追加的方法打开sign.csv
#表头
#ybd = time.localtime("%U")
SIGN_FILE_HANDLER.write('签到记录\n,%s,%s,%s,%s\n' %("姓名",'部门','工号','时间'))
errornum = 0 #异常判断参数,0为正常,大于3的时候表示错误
#逻辑处理模块
class SignpageHandler(web.RequestHandler):
def get(self):
try:
self.render('sign.html')
gc.collect()
except:
print("Error!\n 返回签到页面时出现异常")
def post(self, *args, **kwargs): #接受来自前端的信息
try:
user = self.get_argument('user')
depar = self.get_argument('depar')
num = self.get_argument('num')
#写入到sign.csv文件
nowtime = time.localtime()
print(user,depar,num,"time:%s" %(nowtime)) #在后端打印最新签到数据
signtime = time.strftime("%U:%u:%F %H:%M:%S") #获取当前时间(一年中第几周的星期几,年月日,24小时制时间)
SIGN_FILE_HANDLER.write('%s,%s,%s,%s\n' %(user,depar,num,signtime)) #写入文件
SIGN_FILE_HANDLER.fileno()
self.write('签到成功,时间:%s' %(signtime))
gc.collect()
except:
t = time.strftime("%F %H:%M:%S")
print("Error!\n 在签到页面出现异常 time:%s" %t)
else:
t = time.strftime("%F:%H:%M:%S")
print("客户端访问签到页面一次,没有发生意外 time:%s" %t)
# 用户签到处理模块;
class SignPageHandlers(web.RequestHandler):
# 当用户请求为get时,跳转页面到签到页面;
def get(self, *args, **kwargs):
self.render("sign.html")
# 当用户请求为post时,对用户提交信息做验证,并存储签到信息到文件中;
def post(self, *args, **kwargs):
name = self.get_argument('name')
department = self.get_argument('department')
num = self.get_argument('num')
if name and department and num:
print(name, department, num)
# 将用户签到信息写入文件中;
SIGN_FILE_HANDLER.write('%s,%s,%s\n' %(name, department, num))
# 手动刷新, 将缓冲区内容写入的文件;
SIGN_FILE_HANDLER.flush()
self.write('签到成功!')
else:
self.write('请填写正确的签到信息!')
#网站路由
try:
application = web.Application([
(r"/signs",SignPageHandlers),
(r"/sign", SignpageHandler), # 签到页面
(r"/webcs",WEB_TWOHTML_FILE), #web测试页面
])
except:
print("Error!\n 路由出现错误")
#服务(前台)
if __name__ == '__main__':
##18年老项目了,没写静态文件分离和日志记录等功能
host_name = socket.gethostname() # 获取主机名
ip_address = socket.gethostbyname(host_name) # 获取主机名对应的IP地址
url = ('http://' + ip_address + ':' + port) #拼接出url
urlindex = ('http://' + ip_address + ':' + port + '/index') #拼接出首页url
print("url: %s \n主页::%s" % (url,urlindex))
http_server = httpserver.HTTPServer(application)
http_server.listen(port) #监听端口
ioloop.IOLoop.current().start()
这样就完成了大部分的工作了,剩下的根据自己需求调整即可。
最后附上我的项目仓库:
仓库地址:https://gitee.com/wubie/custom-online-sign-in