第三节 服务器
一、服务器的基础知识
服务器是一个管理资源的计算机,它可以让用户通过网络进行访问。
二、flask
flask是Python的一个库,使用它可以搭建一个服务器。
要使用flask,我们需要先对资源做如下布局:
展开后:
三、导库创建服务器应用
代码展示:
from flask import Flask
app = Flask(__name__)
Flask 类中的功能函数:
功能函数 | 作用 |
---|---|
route() | 识别请求网址路径 |
closing() | 关闭链接功能 |
run() | C启动服务器应用对象 |
四、启动服务器应用对象
调用服务器应用对象的run功能函数,进行启动:
代码展示:
from flask import Flask
app = Flask(__name__)
app.run()
注意:run()方法在不传入任何参数的情况下,启动的网址为 127.0.0.1:5000
五、路由和函数
使用服务器应用对象的route功能函数能够识别请求网址,并通过@符号来关联并触发一个自定义的函数。
@app.route("网址路径")
def index():
return "你好,服务器!"
1、@是关联并触发index函数
2、"/" 代表当前位置
请求网址 | 对应的路由设置 |
---|---|
http://127.0.0.1:5000/ | @app.route("/") |
完整代码:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
return "你好,服务器!"
app.run()
运行效果:
服务器程序只有不停的在运行,才能随时随地让其他人通过网络进行访问。
路由与函数的基本原则:一 一 对应紧相连
六、不同的网页请求
浏览器中的请求网址 | 对应的路由 | 执行函数 | 浏览器呈现的内容 |
---|---|---|---|
http://127.0.0.1:5000 | @app.route("/") | index | 在网页中再次…….! |
http://127.0.0.1:5000/login | @app.route("/login") | login | 欢迎来到登录页面 |
示例代码:
from flask import Flask
app = Flask(__name__)
@app.route("/")
def index():
return "在网页中再次见到Python的强大之处!"
@app.route("/login")
def login():
return "欢迎来到登录界面!"
app.run()
执行效果:
return返回当前内容,内容可以是字符串、数字、html。
七、渲染HTML
from flask import render_template
render_template("html文件名")
注意:Html文件名必须放在templates文件夹下
例如:渲染个人网页:render_template("index.html")
八、render_template
通过设置render_template函数的第二个参数,就能将数据传递到HTML中。
语法:render_template("html文件名",变量名 = 数据)
注意:
1、变量名必须存在,用于HTML接收(在符合变量命名的规则下可以任意命名)
2、数据可以是任何数据类型(字符串、数字、变量、字典、列表…)
例如:render_template("index.html",news = "武汉樱花节")
九、模板语法
模板语法能够接收从服务器传入的变量数据,并且呈现变量对应的动态内容。
模板语法主要有两类:变量和控制语句
9.1 模板语法—变量
<html标签>{{变量名}}</html标签>
说明:
1、变量名是用来接收传入的数据;
2、变量名必须与传入的变量名保持一致
举栗子: Python中的函数返回值为:
render_template("index.html",news = "武汉樱花节")
inex.html中接收数据的代码为:
<p></p> 或者 <h1></h1>
易错点:
1、变量名必须放在两对大括号中;
2、变量名必须存在,且和传入的变量名相同;
9.2 模板语法-for循环
常用的控制语句:for循环和条件判断 语法格式
{% for 变量名 in 列表名 %}
<标签>{{变量名}}</标签>
{% endfor %}
说明: 1、完整的for循环语句包含三部分:头(for循环语句开始)体(循环体)、尾(for循环语句结束)
2、循环头和循环尾都必须嵌套在{% %}内部
十、创建带有链接的图片
语法:
<a href="链接网址">
<img src="图标的地址">
</a>
添加“默契大考验”入口,在index.html中的body标签内:
<a href="/privatepic">
<img src='../static/images/默契.gif'>
</a>
十一、form标签
在HTML中,通常将form标签和一些其他的标签进行组合连用来实现答题页面。
<form action="/privatepic">
<p>我的名字叫什么?</p>
<input name="who"/>
<button> 提交 </button>
</form>
说明:
1、action属性用于指定form表单提交的目的地(路由中的网址)
2、<input>标签实现输入框效果,其name属性是给输入框命名,便于服务器对用户输入的数据接收
3、<button>标签实现提交按钮效果(在IE浏览器中不支持提交功能)
注意:标签的左尖括号(<)与单词之间不能存在空格
注意事项:如果标签的左尖括号(<)与单词之间存在空格,那么该标签中的内容就不能正常显示,而且这个标签上添加的css样式也是不能呈现出来的。
十二、接收数据
在Python程序中,使用get功能函数来接收用户在HTML页面的输入框内输入的内容。
语法:
from flask import request
变量名 = request.values.get("HTML中input标签的name属性值")
注意:get()功能函数的name属性值与字符串之间不存在任何空格
举例: 在privatepic.html中存在input标签如下:
<input name="who">
Python中接收用户在input标签上输入的内容为:
request.values.get("who")
十三、文件上传
<form action="路由网址"
method="post" enctype="multipart/form-data" >
<input name='title'/>
<input type="file" name="file"/>
<button> 提交 </button>
</form>
注意:1、input标签的type属性值默认是"text"(文本类型),如果用于上传文件,必须设置type = "file" (文件类型)
2、若表单中包含文件类型的输入框,必须在form标签中指定method="post" 属性,默认是"get"
3、由于该表单含有多种input类型数据(文本、文件),所以必须在form标签中指定enctype="multipart/form-data" 属性
4、enctype是encodetype(编码类型)的缩写。
5、multipart/form-data是指表单数据有多部分构成,既有文本,又有文件等数据。
十四、post方法
实现上传文件功能,必须使用form表单的post方法向服务器发送请求,那么服务器中的Python程序也必须使用post方法来接收。
form表单的应用
1、向服务器发送携带数据的请求(使用post方法发送)
在html中:
<form method="post" action="/processwork">....</form>
2、服务器接收数据并处理(必须使用post方法接收)
在Python中:
@app.route("/processwork",methods=["POST"])
注意:
1、methods的属性值是一个列表,列表元素是大写的"POST"字符串
2、此设置只接收post方法请求,不再接收get方法请求
“作品上传”中form表单对应的HTML代码更新为:(post方法)
<form method="post" action="/processwork">
....
</form>
新增"/processwork"路由对应的Python代码:(post方法)
@app.route("/processwork",methods = ["POST"])
def process_work():
return ……
十五、接收并保存文件
在Python程序中,需要使用request模块中子模块files的get功能函数来接收文件数据。
语法: 变量名 = request.files.get("input标签的name属性值")
1、使用request模块中子模块files的get功能函数来接收文件数据
变量名 = request.files.get("input标签的name属性值")
2、接收到的文件数据在服务器上没有存储地址,而需要一个地址,因此需要将获取到的文件数据进行保存操作
文件存放在static文件夹下的images文件夹中。
# 接收文件数据对象,并赋值给变量file
file = request.files.get('file')
# 通过file对象的filename属性获取文件名
fname = file.filename
# 通过学而思封装的函数获取存储文件的绝对路径
fpath = save_path(fname)
# 通过file对象的save功能函数存储文件
file.save(fpath)
十六、pickle模块
pickle是Python中的模块,它能够将Python数据(列表、字典、字符串等)进行永久性保存,保存形式通常是pickle文件。
说明:pickle文件,就是以.pickle为后缀名的文件(例如:works.pickle 、news.pickle)
当使用pickle保存Python数据到pickle文件时,数据是原样保存,原样读取(就像照镜子)
16.1 pickle保存Python数据
pickle模块中的dump函数能够将Python数据保存到pickle文件中。
语法:
import pickle
with open("文档名.pickle","wb") as 变量名:
pickle.dump(存入的数据,变量名)
说明: dump函数有两个参数,第一个是存入的数据(任意类型),第二个是打开的文件
注意: 1、打开的文档格式是.pickle格式(若不存在,程序自动创建)
2、打开文档的模式必须是"wb",其中"w"是write的缩写,"b"是bytes(字节)的缩写;因为通过pickle对数据进行存储时,必须用二进制(b)模式写入文件.
打开pickle文档,保存作品数据(works变量)
import pickle
with open("works.pickle","wb") as f:
pickle.dump(works,f)
16.2 读取Python数据
语法:
with open("文档名.pickle","rb") as f:
变量 = pickle.load(f)
说明:load函数有一个参数,表示打开的pickle文件
注意:1、读取文件时需要确保文件已存在,否则会报错。
2、读取文件时需要用"r"(read)模式打开文档,又因为存入时使用的是"wb",因此读取时需要使用"rb"。
打开pickle文档,读取作品数据的代码如下:
with open("works.pickle","rb") as f:
works = pickle.load(f)
十七、重定向
重定向(redirect)就是将网络请求重新定位到其它位置。
语法:
from flask import redirect
@app.route(….)
def 函数名():
….
return redirect('路由网址')
例如:1、redirect('/') 跳转到默认网址中对应的网页
2、redirect('/privatepic') 跳转到默契大考验对应的网页
十八、携带数据的请求方式
通常情况下,使用get方法向服务器发送携带数据的请求有两种方式:
1、使用form表单的get方法(适用用户输入场景):
拼接的网址为:http://127.0.0.1:5000 + form标签的action属性值(路由网址) + 问号(?) + input标签的name值(变量名)= 输入的数据(值)
2、使用a标签(手动将携带的数据添加到链接中)
<a href = "路由网址 ? 变量名=值"></a>
说明:以上两种方式的网址组成部分都是相同的
十九、接收a标签中携带的数据
携带数据的a标签
向服务器发送携带数据的请求(在HTML中)
<a href = "路由网址?变量名=值"></a>
接收携带的数据(在Python中)
变量名 = request.values.get("变量名")
说明:此应用与form表单的应用类似
获取删除的作品
向服务器发送携带数据的请求(在HTML中)
<a href = "/delete?worktitle={{work['title']}}"></a>
接收携带的数据(在Python中)
work_title = request.values.get("worktitle")
二十、文本域输入框
<form action="路由网址" >
<input name="title"/>
<textarea name="变量名"></textarea>
<button> 提交 </button>
</form>
说明:1、此标签需要成对出现,type属性值默认且只能是"textarea"(也是文本类型)
2、此标签能够允许多行数据输入,功能与input标签类似
当在<textarea></textarea>标签中添加内容:
<textarea name="text">我是输入框中默认存在的数据</textarea>
运行效果:
在messageboard.html中body标签内:
<form action="/messageboard">
<p>昵称:</p>
<input name="who"/>
<p>留言:</p>
<textarea name="text"></textarea>
<button>提交</button>
</form>