Bottle学习笔记


笔记放在仓库:https://github.com/Turing-dz/bottle_study_notes

1.环境

使用管理员身份打开cmd

conda create -n bottle python
conda activate bottle
pip install bottle

2.知识点

2.1 框架

1.最少代码的服务器程序

from bottle import run,route
@route('/')
def index():
    return "I am bottle"
run(host="localhost",port="80",debug=True,deloader=True)

2.使用面向对象的服务器程序框架

from bottle import Bottle,run 
web=Bottle()
@web.route("/")
def index():
    return "I am bottle2"
run(web)

服务器运行函数run,指定服务器的运行IP和端口(host,port);显示调试信息(debug);代码修改后自动重启服务(deloader)

2.2 URL装饰器

1.默认响应get请求,可以定义method响应多种请求方法,request.method判断请求方式

from bottle import route, run ,request,get,post
htmlstr="""
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>BOTTLE</title>
</head>
<body>
<form action ="/demo_gp" method="POST">
<input type="submit"/>
</form>
</body>
</html>
"""
@route("/")
def index():
    return htmlstr
@route("/demo_post",method="POST")#1.响应post请求
def pt():
    return "receive method post"
#@route("/demo_gp",method=["POST","GET"])#2.响应两种请求方式
@get("/demo_gp")#3.响应两种请求方法
@post("/demo_gp")
def gp():
    if request.method=="GET":#request.method判断请求的方式
        return htmlstr
    else:
        return "this is post"
run()

2.动态路由

from bottle import route,run ,Bottle
import re
@route("/hello/<name>")#1.路由传递字符串
def index(name=""):
    return "Hello %s"%name
@route("/uid/<uid:int>")#2.路由传递整型
def getuid(uid=0):
    return "your id is %d"%uid
@route("/weight/<weight:float>")#3.路由传递浮点数
def getweight(weight):
    return "your weight:%f"%weight
@route("/getfilepath/<file_path:path>")#4.路由传递路径
def getpath(file_path):
    return file_path
@route("/rege/<ret:re:[0-1]*>")#5.正则匹配路由传递的参数
def rege(ret):
    return ret
#6.自定义路由过滤器
app=Bottle()
def list_filter(config):
    delimiter=config or ","
    regexp=r'\d+(%s\d)*'%re.escape(delimiter)
    def to_python(match):
        return map(int,match.split(delimiter))
    def to_url(numbers):
        return delimiter.join(map(str,numbers))
    return regexp,to_python,to_url
app.router.add_filter('idslist',list_filter)
@app.route("/hello/<ids:idslist>")
def hello(ids):
    res=''
    for i in ids:
        res+=str(i)+'-'
    return "hello %s"%res
run(app,port=80,debug=True) 

2.3 404与url转向

from bottle import route,run,static_file,error,abort,redirect
#1.返回静态文件内容return static_file(filename,root="静态文件地址",mimetype="静态文件类型")
@route("/static/<filename:path>")
def index(filename):
    return static_file(filename,root="",download=True)
#2.强制下载文件,return static_file(filename,root="",download=True/"yourfilename")
@route("/dl/<filename:path>")
def dl(filename):
    return static_file(filename,root='',download="sd.jpg")
#3.指定404页面
@error(404)
def err(err):
    return "页面丢失"
#4.url转向:转向错误abort(404,"error_info"),调用redirect("other url")
@route("/abort")
def ab():
    abort(404,"转向丢失页面")##4.1转向丢失页面
##4.2转向指定页面
@route("/")
def index():
    return "登录成功"
@route("/login/<name>")###登陆成功转向/目录,失败就转向login,且页面丢失
def login(name):
    if name =="abc":
        redirect("/")
    else:
        redirect("/login")

run(port="80",debug=True,reloader=True)

2.4获取get与post请求参数

1.get参数提供:url链接添加”?名称=值&名称=值…“
get 参数获取:request.query.name(当name不存在时,返回空字符串)

from bottle import route, run ,request,get,post
htmlstr="""
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>BOTTLE</title>
</head>
<body>
<form action ="/get_to">
<label>姓名</label>
<input type="text" name="name"/>
<label>电话号码</label>
<input type="text" name="telephone"/>
<label>邮箱</label>
<input type="text" name="email"/>
<input type="submit"/>
</form>
<a href="http://127.0.0.1:8080/get_to?name=1&telephone=2&email=3">提交get信息</a>
</body>
</html>
"""
@route("/")
def index():
    return htmlstr
@route("/get_to")
def getto():
    name=request.query.name#获取
    telephone=request.query.telephone
    email=request.query.email
    return (name,telephone,email)
run(debug=True,reloader=True)

2.post参数提供:在提交的表单中添加method=“post”
post 参数获取:request.forms.get(“name”)

from bottle import route, run ,request,get,post
htmlstr="""
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>BOTTLE</title>
</head>
<body>
<form action ="/post_to" method="POST">
<label>姓名</label>
<input type="text" name="name"/>
<label>电话号码</label>
<input type="text" name="telephone"/>
<label>邮箱</label>
<input type="text" name="email"/>
<input type="submit"/>
</form>
</body>
</html>
"""
@route("/")
def index2():
    return htmlstr
@route("/post_to",method="POST")#post方式接受
def postto():
    name=request.forms.get('name')#post方式提取参数
    telephone=request.forms.get('telephone')
    email=request.forms.get('email')
    return (name,telephone,email)
run(debug=True,reloader=True)

2.5为web客户端返回不同类型数据

from bottle import route,run,Response
@route("/")
def index():
    #return {"a":"djn","b":45,"c":2.3}#1.返回字典
    #return ()#2.返回空
    # dec="abcd"
    # return dec.encode("utf-8") #3.返回字节串
    #return ("sdf","sdf")4.#返回元组或列表,不能返回嵌套的
    #5.Response.charset或者Response.content_type指定返回字节编码
    #Response.charset="gbk"
    #Response.content_type="text/html;charset=gbk"
    return "你好"
run(port="80",debug=True,reloader=True)

2.6使用cookie与signed cookie跟踪客户

from bottle import route,run,response,request
#1.添加cookie, response.set_cookie("name","value")
@route("/")
def index():
    response.set_cookie("zoe","27")
    return "set cookie!"
#2.获取cookie,request.get_cookie("name")
@route("/get_cookie")
def getcookie():
    return request.get_cookie("zoe")
#3.添加签名的cookie,response.set_cookie("name","value",secret="")
@route("/setsign")
def setsign():
    response.set_cookie("dz","28",secret="sfkjskfjdkfkls")
    return "signed cookie"
#4.获取cookie,request.get_cookie("name",secret="")
@route("/getsign")
def getsign():
    return request.get_cookie("dz",secret="sfkjskfjdkfkls")
#5.普通cookie中有中文时,使用urllib.parse.quote编码,urllib.parse.unquote解码;signed_cookie不用设置
from urllib.parse import quote,unquote
@route("/chain_set")
def ch_set():
    response.set_cookie("myname",quote("我是"))
    return "中文cookie"
@route("/chain_get")
def ch_get():
    return unquote(request.get_cookie("myname"))
run(port="80",debug=True,reloader=True)

2.7HTTP上传接收文件

#1.实现上传文件页面<form action ="" method="POST" enctype="multipart/form-data">,<input type="file" name="fileupload"/>,<input type="submit" value="上传文件"/>
from bottle import route,run ,request
htmlstr="""
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>BOTTLE</title>
</head>
<body>
<form action ="/get_file" method="POST" enctype="multipart/form-data">
<input type="file" name="fileupload"/>
<input type="submit" value="上传文件"/>
</form>
</body>
</html>
"""
@route("/")
def index():
    return htmlstr
#2.实现接受上传文件业务的函数,request.files.get("name")
@route("/get_file",method=["GET","POST"])
def getfile():
    if request.method=="GET":
        return htmlstr
    else:
        uf=request.files.get("fileupload")
        uf.save(uf.filename)
        return "接受到了文件,并保存到了本地根目录"
run(port="80",debug=True,reloader=True)

2.8内建模板引擎

#1.嵌入python变量from bottle import template;template("{{name}});template("Str with{{a}} many{{b}} values",**adict)
from bottle import route,run,template
html="""
 begin:{{name}}, {{age}}, {{weight}}, {{courses}}, {{mytest.disp()}},{{!html_str}}:end!
 % if MyScores:
 <table>
    <tr>
        <td>subject</td>
        <td>score</td>
    </tr>
    % for (sub,score) in MyScores.items():
    <tr>
        <td>{{sub}}</td>
        <td>{{score}}</td>
    </tr>
     % end
 </table>
 % else:
 没有查询到scores
 % end
"""
class MyTestClass():
    def __init__(self,x=0,y=0):
        self.x=x
        self.y=y
    def disp(self):
        return (self.x,self.y)
@route("/stu/<name>")
def index(name="Stranger"):
    age=12
    weight=23.32
    html_str="<a href='sfdnsdjfn'>链接</a>"#如何把这个字符串变量传到html时,让它转义为html呢,只需要再html的变量名前加上!
    courses=["english","kero"]
    mytest=MyTestClass()
    #参数太多时,可以打包成字典,然后再解包
    # my=dict(name=name,age=age,weight=weight,courses=courses,mytest=mytest,html_str=html_str)
    # return template(html,**my)
#2嵌入python代码;%开头嵌入单行代码;<%--------%>嵌入多行python代码,
    MyScores={"chinese":334,"english":23,"math":2384}
    return template(html,name=name,age=age,weight=weight,courses=courses,mytest=mytest,html_str=html_str,MyScores=MyScores)
run(port="80",debug=True,reloader=True)

% include(“nav.tpl”),将nav.tpl引入到当前模板中
% rebase("base.tpl)将当前模板文件嵌入到父模板的{{!base}}中 ,其实就是引入父模板。

##父模板base.tpl,这里引入了nav.tpl文件,然后base部分由子模版去继承添加
<!DOCTYPE html>
<html>
<head>    
    <title></title>
</head>
<body>
% include("nav.tpl")
   {{!base}}
</body>
</html>
## nav.tpl文件
<div>
    <a href="#">index1</a>
    <a href="#">index2</a>
    <a href="#">index3</a>
    <a href="#">index4</a>
</div>
##html2template.tpl文件,这里继承了父模板
 % rebase("base.tpl")
 begin:{{name}}, {{age}}, {{weight}}, {{courses}}, {{mytest.disp()}},{{!html_str}}:end!
    % if MyScores:
    <table>
        <tr>
            <td>subject</td>
            <td>score</td>
        </tr>
        % for (sub,score) in MyScores.items():
        <tr>
            <td>{{sub}}</td>
            <td>{{score}}</td>
        </tr>
        % end
    </table>
    % else:
    没有查询到scores
    % end

模板中变量管理函数:define(name),get(name,default=None),setdefault=(name=value)
当return函数没有传递参数时,变量一定要有default值

 %setdefault("variable","dnfjk")
 {{variable}}

拿到变量variable传递的参数,若无就取no字符串为默认值。

 {{get("variable","no")}}

2.9Bottle网站程序的部署

使用waitress同步框架或tornado异步框架,使用nginx进行反向代理。
文件目录如下:

文件目录如下
-nginx
-static
----img
----css
----js
-template
manage.py

对nginx的conf\nginx.conf文件修改内容:

    #111111111111111111111111.指明nginx所代理的后端内容,就是本机上的8088端口启动的文件
    upstream myserver{
        ip_hash;
        server localhost:8088;
        server localhost:8081;
        server localhost:8082;
    }
    server {
        listen       80;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;
    #222222222222222222.在server函数中,写明自己的代理地址,就是1里面设置的名称myserver
        location / {
            root   html;
            index  index.html index.htm;
            proxy_pass http://myserver;
        }
        #3333333333333333333333.将静态文件映射到指定的位置
        location ~ \.(jpg|jpeg|png|gif)$ {
            root C:/Users/dz/Desktop/bottle/static/img;
        }
        location ~ \.js$ {
            root C:/Users/dz/Desktop/bottle/static/js;
        }
        location ~ \.css$ {
            root C:/Users/dz/Desktop/bottle/static/css;
        }

测试nginx配置修改成功

nginx -t

nginx: the configuration file C:\Users\dz\Desktop\bottle\nginx-1.8.0/conf/nginx.conf syntax is ok
nginx: configuration file C:\Users\dz\Desktop\bottle\nginx-1.8.0/conf/nginx.conf test is successful

启动nginx

nginx
#1.使用waitress同步框架部署后端:pip install waitress;tornado 是异步框架;nginx后端反向代理
from bottle import route,run,template
import sys
@route("/")
def index():
    return template("templates/index.html")
port="8088"
if len(sys.argv)==2:
    port=sys.argv[1]
# run(server="waitress",port=port,debug=True,reloader=True)
run(server="tornado",port=port,debug=True,reloader=True)

2.10用户注册与登录

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我是小z呀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值