web服务器进阶

通过上面的学习,我们发现我们的web服务器没有彻底解耦

1、实现自己指定端口运行我们的web服务器

如果我们的web服务器端口被占用,那么我们的web服务器直接挂掉。

怎么实现?我们可以在执行的时候指定一个端口。

复习:

创建一个Demo.py

写上:

import sys

print(sys.argv)

我们在黑窗口运行一个python文件的时候,执行命令:

python Demo 123 456

会输出:['Demo.py', '123', '456']

可见,我们是可以给一个程序传递参数的。我们用这个功能,来给我们的web服务器指定端口和框架。

2、利用1中的例子,再给一个框架名,让他直接传一个框架进入。

我们希望运行 python web服务器 7891 Demo:application

来实现调用Demo框架的application方法。

3、写一个配置文件,将web服务器中的寻找文件的路径写进去。

解决上面三个问题才是真的解耦。

思路已经提供给大家,并且看基础是能够写出来的。

接下来我们利用装饰器完成路由功能。对装饰器不懂的可以看看这篇文章:python基础三

什么是路由功能?

就是请求的url,我们上次通过if判断来写的,很恶心,用另一种方法些

我们将Demo框架写成这样(不用再修改web服务器了):

URL_FUNC_DICT = dict()

def url_func(url):

def set_fun(func):

URL_FUNC_DICT[url] = func

def call_func(*args,**kwargs):

return func(*args,**kwargs)

return call_func

return set_fun

@url_func('/login.py')

def login():

# 这里也可以读取文件

return '<h1>登录的页面</h1>'

@url_func('/create.py')

def create():

return '<h1>注册的页面</h1>'

def application(evairon,start_response):

# 第一个参数返回状态码,第二个以键值的方式返回你想添加的head部分

start_response('200 ok',[('Content-Type','text/html;charset=utf-8')])

# 返回给网页的内容

try:

file_name = evairon['path_info']

fun = URL_FUNC_DICT[file_name]

return fun()

except Exception as e:

return '未找到文件'

伪静态实现

在前面说过我们只是暂时任务请求以.py结尾的url为动态的。实际上不是这样。

上面才是动态网页?

静态的:域名/index.html

动态的:域名/index.aspx?page=xxx&xxxxx=xxxx,

伪静态:域名/cour/index.html

web服务器实现伪静态:

修改web服务器中判断是.py结尾为以.html结尾,其它不用管。

修改Demo框架中装饰器的参数为.html结尾。

给Demo框架连接数据库并显示到页面

数据库运用我们mysql教程中给大家演示的那个student数据库。

对于python操作数据库没了解的请去看mysql数据库系列文章。

mysql简单基础,我们在Demo新创建一个mysqldata方法,并且加上装饰器

@url_func('/mysqldata.html')

def mysqldata():

conn = connect(host='localhost',port=3306,user='root',password='123456',database='student',charset='utf8')

cursor = conn.cursor()

cursor.execute("select * from studentinfo")

text = cursor.fetchall()

cursor.close()

conn.close()

return str(text)

在浏览器中输入127.0.0.1:端口号/mysqldata.html即可看到内容。

查出来是这样的:((1, '张三', 1, '男', 23, '武汉', b'\x00'), (2, '小花', 2, '女', 20, '长沙', b'\x00'), (3, '李四', 3, '男', 21, '上海', b'\x00'), (4, '小猫', 1, '女', 18, '北京', b'\x00'), (6, '小狗', 3, '女', 25, '成都', b'\x00'), (7, '赵六', 1, '男', 26, '天津', b'\x00'))

看着很恶心,给个格式。修改mysqldata方法:

这里会用到html的知识点,希望自己补充。修改成:

@url_func('/mysqldata.html')

def mysqldata():

conn = connect(host='localhost',port=3306,user='root',password='123456',database='student',charset='utf8')

cursor = conn.cursor()

cursor.execute("select * from studentinfo")

text = cursor.fetchall()

cursor.close()

conn.close()

html = "<table border='1' width = '400px' cellspacing='0' cellpadding='0'>"

tr_html = '''

<tr>

<td>%s</td>

<td>%s</td>

<td>%s</td>

<td>%s</td>

<td>%s</td>

<td>%s</td>

<td>%s</td>

</tr>

'''

for item in text:

html += tr_html %(item[0],item[1],item[2],item[3],item[4],item[5],item[6])

html +="</table>"

return str(html)

这样就好看多了。当然你想显示什么就数据库查什么就好了。

完善Demo框架

1、给路由添加正则

现在我们的url返回的都是固定的,比如我们想要删除一个数据,请求的url为/delete/xxx.html

我们需要传递一个xxx,表示id,这个id是不确定的,所以我们需要正则匹配,只要是这种格式,我们都执行

delete方法。修改如下:

修改application方法:

def application(evairon,start_response):

# 第一个参数返回状态码,第二个以键值的方式返回你想添加的head部分

start_response('200 ok',[('Content-Type','text/html;charset=utf-8')])

# 返回给网页的内容

try:

file_name = evairon['path_info']

for url,func in URL_FUNC_DICT.items():

# 匹配是否有这个函数,有返回回去

ret = re.match(url,file_name)

if ret:

return func(ret)

except Exception as e:

return '未找到文件 %s'%e

添加delete方法,并匹配所有url为/delete/xxx.html格式的都执行该方法。

@url_func(r'/delete/(\d+)\.html')

def delete(ret):

return '删除方法。ok'

由于给所有函数传递了一个url,所以需要给上面的函数都添加一个参数。

执行:成功返回删除方法。ok,那我们继续完善删除方法。

@url_func(r'/delete/(\d+)\.html')

def delete(ret):

# 获取id值

id = ret.group(1)

# 执行sql删除

conn = connect(host='localhost',port=3306,user='root',password='123456',database='student',charset='utf8')

cursor = conn.cursor()

count = cursor.execute("delete from studentinfo where studentid = %s",(id,))

if count:

conn.commit()

cursor.close()

conn.close()

return '删除成功。ok!!'

else:

return '删除失败!'

其他修改啊,添加,只是sql语句不同,都大同小异。

不过在修改的时候要修改正则,传给数据的还要有修改值没有了解post请求就换个正则匹配

比如127.0.0.1/修改方法/要修改的id/要修改的内容.html,用正则匹配出id和要修改的内容就可以了。

但是有个问题,当我们传递的内容或者汉子的时候会出现乱码,因为是通过url传递的,中途会有个url编码的过程,

我们需要解码:

1、需要导入模块

import urllib

解码:urllib.parse.unquote()

编码:urllib.parse.quote()

添加日志模块

不会日志模块需要看基础:python常用模块二

导入日志模块:import logging

修改application方法:

def application(evairon,start_response):

# 第一个参数返回状态码,第二个以键值的方式返回你想添加的head部分

start_response('200 ok',[('Content-Type','text/html;charset=utf-8')])

file_name = evairon['path_info']

# 写入日志

logging.basicConfig(level=logging.INFO,

filename = './log.txt',

filemode = 'a',

format = '%(asctime)s - %(filename)s[line:%(lineno)d]-%(levelname)s:%(message)s'

)

logging.info('访问了%s'%file_name)

# 返回给网页的内容

try:

for url,func in URL_FUNC_DICT.items():

# 匹配是否有这个函数,有返回回去

ret = re.match(url,file_name)

if ret:

return func(ret)

except Exception as e:

logging.WARNING('找不到文件')

return '未找到文件 %s'%e

原文发布于微信公众号 - python入门到放弃(gh_30a7ea796e72)

原文发表时间:2018-12-06

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

扫码关注云+社区

领取腾讯云代金券