15158846557 在线咨询 在线咨询
15158846557 在线咨询
所在位置: 首页 > 营销资讯 > 网站运营 > Python Web 开发框架Flask快速入门

Python Web 开发框架Flask快速入门

时间:2023-05-29 01:36:01 | 来源:网站运营

时间:2023-05-29 01:36:01 来源:网站运营

Python Web 开发框架Flask快速入门:

Python Web 开发框架Flask快速入门




WEB数据库系统


Web 2.0专注于让网站上的用户生成内容,自从它开始,网络编程就成为了热门话题。一直以来都可以使用Python创建网站,但这是一个相当无聊的任务。因此,有很多框架和工具被创造出来,帮助开发人员创建更快,更强大的网站。本文描述了一些将Python和Web服务器组合以创建动态内容的方法。这不是一个完整的介绍,因为这个话题过于广泛,不可能在一篇文章中讲清楚。所以本次课程主要讲解PythonWeb框架中常用的Flask框架的使用。





了解框架:


Flask作为Web框架,它的作用主要是为了开发Web应用程序。那么我们首先来了解下Web应用程序。Web应用程序 (World Wide Web)诞生最初的目的,是为了利用互联网交流工作文档。





一切从客户端发起请求开始。





安装框架

pip install flask





最小的Flask应用程序




编写代码


一个最小的 Flask 应用看起来会是这样,找到一个目录新建一个Python文件,比如叫做 helloFlask.py,编写代码如下:


from flask import Flaskapp = Flask(__name__)@app.route('/')def hello_world(): return 'Hello World!'if __name__ == '__main__': app.run()


运行


运行Flask项目只需要执行编写的Python文件即可:


python helloFlask.py
运行成功会看到如下页面:





在浏览器访问:









外部可访问的服务器


如果你运行了这个服务器,你会发现它只能从你自己的计算机上访问,网络中其它任何的地方都不能访问。在调试模式下,用户可以在你的计算机上执行任意 Python 代码。因此,这个行为是默认的。

如果你禁用了 debug 或信任你所在网络的用户,你可以简单修改调用 run() 的方法使你的服务器公开可用,如下:


app.run(host='0.0.0.0')
这会让操作系统监听所有网络。





路由


现代 Web 应用的 URL 十分优雅,易于人们辨识记忆,这一点对于那些面向使用低速网络连接移动设备访问的应用特别有用。如果可以不访问索引页,而是直接访问想要的那个页面,他们多半会笑逐颜开而再度光顾。

如上所见, route() 装饰器把一个函数绑定到对应的 URL 上。

这里是一些基本的例子:


@app.route('/')def index(): return 'Index Page'@app.route('/hello')def hello(): return 'Hello World'
但是,不仅如此!你可以构造含有动态部分的 URL,也可以在一个函数上附着多个规则。





模板


怎么给服务器的用户呈现一个漂亮的页面呢?

肯定需要用到 html、css ,如果想要更炫的效果还要加入 js ,问题来了,这么一大堆字段串全都写到视图中通过 return 返回,这样定义就太麻烦了吧,因为定义字符串是不会出任何效果和错误的,如果有一个专门定义前端页面的地方就好了。

为此Flask 配备了 Jinja2 模板引擎。





创建模板


Flask 会在 templates 文件夹里寻找模板。所以,如果你的应用是个模块,这个文件夹应该与模块同级;如果它是一个包,那么这个文件夹作为包的子目录:

例如在应用下的template文件夹下创建模板index.html





接下来你可以使用 render_template() 方法来渲染模板。你需要做的一切就是将模板名和你想作为关键字的参数传入模板的变量。这里有一个展示如何渲染模板的简例:


from flask import render_template@app.route('/index/')def hello(name=None): name = "张三" return render_template('index.html', name=name)
index.html 中添加如下代码:


<!doctype html><title>Hello from Flask</title>{% if name %} <h1>Hello {{ name }}!</h1>{% else %} <h1>Hello World!</h1>{% endif %}
运行Flask 程序输入 127.0.0.1:5000/index 即可看到如下结果:









模板的基本语法


模板中使用变量:



使用判断语句:


{% if name %}{% else %}{% endif %}
使用循环语句:


{% for i in range(1,10) %} {% for j in range(1,i+1) %} {{ j }} x {{ i }} = {{ i*j }} {% endfor %} <br>{% endfor %}


ORM


我们之前操作数据库是通过写sql语句,那么能不能不写sql语句就可以操作数据库呢? 答案是可以的。

ORM框架
O是object,也就类对象的意思,R是relation,翻译成中文是关系,也就是关系数据库中数据表的意思,M是mapping,是映射的意思。在ORM框架中,它帮我们把类和数据表进行了一个映射,可以让我们通过类和类对象就能操作它所对应的表格中的数据。ORM框架还有一个功能,它可以根据我们设计的类自动帮我们生成数据库中的表格,省去了我们自己建表的过程。









模型设计


在Flask中使用mysql数据库,需要安装一个flask-sqlalchemy的扩展。


pip install flask-sqlalchemy
要连接mysql数据库,还需要安装 flask-mysqldb


pip install flask-mysqldb


flask连接数据库


下列代码即可连接本机MySQL的test3数据库,假设用户名为root,密码为mysql


app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:mysql@127.0.0.1:3306/test3'


定义模型类进行数据库操作

from flask import Flaskfrom flask_sqlalchemy import SQLAlchemyapp = Flask(__name__)#设置连接数据库的URLapp.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:mysql@127.0.0.1:3306/Flask_test'#设置每次请求结束后会自动提交数据库中的改动app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = Trueapp.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True#查询时会显示原始SQL语句app.config['SQLALCHEMY_ECHO'] = Truedb = SQLAlchemy(app)class Role(db.Model): # 定义表名 __tablename__ = 'roles' # 定义列对象 id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64), unique=True) us = db.relationship('User', backref='role')class User(db.Model): __tablename__ = 'users' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(64), unique=True, index=True) email = db.Column(db.String(64),unique=True) pswd = db.Column(db.String(64)) role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))if __name__ == '__main__': db.drop_all() db.create_all() ro1 = Role(name='admin') ro2 = Role(name='user') db.session.add_all([ro1,ro2]) db.session.commit() us1 = User(name='wang',email='wang@163.com',pswd='123456',role_id=ro1.id) us2 = User(name='zhang',email='zhang@189.com',pswd='201512',role_id=ro2.id) us3 = User(name='chen',email='chen@126.com',pswd='987654',role_id=ro2.id) us4 = User(name='zhou',email='zhou@163.com',pswd='456789',role_id=ro1.id) db.session.add_all([us1,us2,us3,us4]) db.session.commit() app.run(debug=True)
代码解释:





创建表:

db.create_all()


删除表:

db.drop_all()


插入一条数据:

ro1 = Role(name='admin')db.session.add(ro1)db.session.commit()#再次插入一条数据ro2 = Role(name='user')db.session.add(ro2)db.session.commit()


一次插入多条数据

us1 = User(name='wang',email='wang@163.com',pswd='123456',role_id=ro1.id)us2 = User(name='zhang',email='zhang@189.com',pswd='201512',role_id=ro2.id)us3 = User(name='chen',email='chen@126.com',pswd='987654',role_id=ro2.id)us4 = User(name='zhou',email='zhou@163.com',pswd='456789',role_id=ro1.id)db.session.add_all([us1,us2,us3,us4])db.session.commit()


查询:filter_by精确查询


返回名字等于wang的所有人


User.query.filter_by(name='wang').all()


first()返回查询到的第一个对象

User.query.first()


all()返回查询到的所有对象

User.query.all()


filter模糊查询,返回名字结尾字符为g的所有数据。

User.query.filter(User.name.endswith('g')).all()


get(),参数为主键,如果主键不存在没有返回内容

User.query.get()


逻辑非,返回名字不等于wang的所有数据。

User.query.filter(User.name!='wang').all()


逻辑与,需要导入and,返回and()条件满足的所有数据。

from sqlalchemy import and_User.query.filter(and_(User.name!='wang',User.email.endswith('163.com'))).all()


逻辑或,需要导入or_

from sqlalchemy import or_User.query.filter(or_(User.name!='wang',User.email.endswith('163.com'))).all()


查询数据后删除

user = User.query.first()db.session.delete(user)db.session.commit()User.query.all()


更新数据

user = User.query.first()user.name = 'dong'db.session.commit()User.query.first()


使用update

User.query.filter_by(name='zhang').update({'name':'li'})


关联查询示例:角色和用户的关系是一对多的关系,一个角色可以有多个用户,一个用户只能属于一个角色。


查询角色的所有用户:


#查询roles表id为1的角色ro1 = Role.query.get(1)#查询该角色的所有用户ro1.us
查询用户所属角色:


#查询users表id为3的用户us1 = User.query.get(3)#查询用户属于什么角色us1.role
总的来说使用Flask进行数据库开发的步骤如下:


  1. 配置连接数据库的选项
  2. 定义模型类
  3. 通过类和对象完成数据库增删改查操作



案例


基本知识点已经学完了,接下来完成一个示例项目:

现在还需要的代码包括三个方面,三个方面顺序不分先后。


  1. 定义视图
  2. 定义模板
  3. 连接操作数据库

目标是完成城市应用的增删改查功能。

表结构如下:

| 列名 | 说明 | 类型 | | --- | --- | --- | | id | 表id(自动递增,主键) | int | | provincename | 省名 | varchar | | cityname | 省会名 | varchar | | usernumber | 用户数量 | int |


要求实现Flask对数据库的增删改查操作。





定义视图、连接操作数据库

from flask import Flask,render_template,request,redirectfrom flask_sqlalchemy import SQLAlchemyapp = Flask(__name__)db = SQLAlchemy(app)#设置数据库连接app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:asd8283676@127.0.0.1:3306/web'#定义模型class City(db.Model): #表模型 id = db.Column(db.Integer,primary_key=True,autoincrement=True) provincename = db.Column(db.String(255)) cityname = db.Column(db.String(255)) usernumber = db.Column(db.Integer)#查询所有数据@app.route("/select")def selectAll(): cityList = City.query.order_by(City.id.desc()).all() return render_template("index.html",city_list = cityList)@app.route('/')def index(): return selectAll()#添加数据@app.route('/insert',methods=['GET','POST'])def insert(): #进行添加操作 province = request.form['province'] cityname = request.form['city'] number = request.form['number'] city = City(provincename=province,cityname=cityname,usernumber=number) db.session.add(city) db.session.commit() #添加完成重定向至主页 return redirect('/')@app.route("/insert_page")def insert_page(): #跳转至添加信息页面 return render_template("insert.html")#删除数据@app.route("/delete",methods=['GET'])def delete(): #操作数据库得到目标数据,before_number表示删除之前的数量,after_name表示删除之后的数量 id = request.args.get("id") city = City.query.filter_by(id=id).first() db.session.delete(city) db.session.commit() return redirect('/')#修改操作@app.route("/alter",methods=['GET','POST'])def alter(): # 可以通过请求方式来改变处理该请求的具体操作 # 比如用户访问/alter页面 如果通过GET请求则返回修改页面 如果通过POST请求则使用修改操作 if request.method == 'GET': id = request.args.get("id") province = request.args.get("provincename") cityname = request.args.get("cityname") usernumber = request.args.get("usernumber") city = City(id = id,provincename=province,cityname=cityname,usernumber = usernumber) return render_template("alter.html",city = city) else: #接收参数,修改数据 id = request.form["id"] province = request.form['province'] cityname = request.form['city'] number = request.form['number'] city = City.query.filter_by(id = id).first() city.provincename = province city.cityname = cityname city.usernumber = number db.session.commit() return redirect('/')if __name__ == "__main__": app.run(debug = True,host='0.0.0.0',port=8080)


定义模板


主页:
index.html


<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>首页</title></head><body> <div align="center"> <br> <a href="insert_page">添加城市</a> <br> <br> <table width="600" cellpadding="5" align="center" border="1" cellspacing="0"> <th align="center" colspan="4">城市信息</th> <tr> <td>province</td> <td>cityname</td> <td>usernumber</td> <td>操作</td> </tr> {% for item in city_list %} <tr> <td>{{item.provincename}}</td> <td>{{item.cityname}}</td> <td>{{item.usernumber}}</td> <td><a href='/alter?id={{item.id}}&provincename={{ item.provincename }}&cityname={{ item.cityname }}&usernumber={{item.usernumber}}'>编辑</a> <a href="/delete?id={{ item.id }}">删除</a> </td> </tr> {% endfor %} </table> </div></body></html>
修改页面
alter.html


<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>修改</title></head><body><div class="layui-main"> <div class="site-content"> <br><br> <h1 class="site-h1">修改信息</h1> <br><br> <form class="layui-form" action="alter" method="post"> <input type="hidden" name = 'id' value="{{city.id}}"> <div class="layui-form-item"> <label class="layui-form-label">省份</label> <div class="layui-input-block"> <input type="text" name="province" required lay-verify="required" placeholder="请输入省份" autocomplete="off" class="layui-input" value="{{city.provincename}}"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">城市</label> <div class="layui-input-block"> <input type="text" name="city" required lay-verify="required" placeholder="请输入城市名称" autocomplete="off" class="layui-input" value="{{city.cityname}}"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">人数</label> <div class="layui-input-block"> <input type="number" name="number" required lay-verify="required" placeholder="请输入人数" autocomplete="off" class="layui-input" value="{{city.usernumber}}"> </div> </div> <div class="layui-form-item"> <div class="layui-input-block"> <button class="layui-btn" lay-submit lay-filter="formDemo">立即提交</button> <button type="reset" class="layui-btn layui-btn-primary">重置</button> </div> </div> </form> </div></div></body></html>
添加数据页面
insert.html


<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>增加</title></head><body><div class="layui-main"> <div class="site-content"> <br><br> <h1 class="site-h1">添加信息</h1><br><br> <form class="layui-form" action="insert" method="post"> <div class="layui-form-item"> <label class="layui-form-label">省份</label> <div class="layui-input-block"> <input type="text" name="province" required lay-verify="required" placeholder="请输入省份" autocomplete="off" class="layui-input"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">城市</label> <div class="layui-input-block"> <input type="text" name="city" required lay-verify="required" placeholder="请输入城市" autocomplete="off" class="layui-input"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">用户数</label> <div class="layui-input-block"> <input type="number" name="number" required lay-verify="required" placeholder="请输入用户数量" autocomplete="off" class="layui-input"> </div> </div> <div class="layui-form-item"> <div class="layui-input-block"> <button class="layui-btn" lay-submit lay-filter="formDemo">立即提交</button> <button type="reset" class="layui-btn layui-btn-primary">重置</button> </div> </div> </form> </div></div></body></html>


执行项目、查看效果、测试功能










网页美化




下载LayUI


在LayUI官网 下载layui相关组件。





项目引入


将Layui相关文件放入项目的static目录下(static目录用于存放静态文件如cssjs文件可以让网站看起来更加美观)。





引入LayUI需要在HTML文件中导入LayUI的CSS文件和JS模块,格式如下:












修改项目HTML文件


index.html:


<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>首页</title> <link rel="stylesheet" href="/static/layui/css/layui.css"></head><body> <div align="center"> <br> <a href="insert_page">添加城市</a> <br> <br> <table id = 'tabledemo'lay-filter="test"> <thead> <tr> <th lay-data="{field:'id', width:100}">编号</th> <th lay-data="{field:'provincename', width:100}">省份</th> <th lay-data="{field:'cityname', width:80, sort:true}">城市名称</th> <th lay-data="{field:'usernumber'}">用户数量</th> <th lay-data="{fixed: 'right', width: 165, align:'center', toolbar: '#barDemo'}"></th> </tr> </thead> <tbody> {% for item in city_list %} <tr> <td>{{item.id}}</td> <td>{{item.provincename}}</td> <td>{{item.cityname}}</td> <td>{{item.usernumber}}</td> </tr> {% endfor %} </tbody> </table> </div><script type="text/html" id="barDemo"> <a class="layui-btn layui-btn-xs" lay-event="edit">编辑</a> <a class="layui-btn layui-btn-danger layui-btn-xs" lay-event="del">删除</a></script><script src="/static/layui/layui.js"></script><script> layui.use('table', function () { var table = layui.table;//转换静态表格 table.init('test', { height: 1000, width: 600//设置高度 ,limit:100 }); table.on('tool(test)', function(obj){ //注:tool 是工具条事件名,test 是 table 原始容器的属性 lay-filter="对应的值" var data = obj.data //获得当前行数据 ,layEvent = obj.event; //获得 lay-event 对应的值 if(layEvent === 'detail'){ layer.msg('查看操作'); } else if(layEvent === 'del'){ layer.confirm('真的删除行么', function(index){ location.href='/delete?id='+data.id; }); } else if(layEvent === 'edit'){ location.href='/alter?id=' + data.id + "&provincename=" +data.provincename + "&cityname=" + data.cityname + "&usernumber=" + data.usernumber; } }); });</script></body></html>
alter.html:


<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>修改</title> <link rel="stylesheet" href="/static/layui/css/layui.css"></head><body><div class="layui-main"> <div class="site-content"> <br><br> <h1 class="site-h1">修改信息</h1> <br><br> <form class="layui-form" action="alter" method="post"> <input type="hidden" name = 'id' value="{{city.id}}"> <div class="layui-form-item"> <label class="layui-form-label">省份</label> <div class="layui-input-block"> <input type="text" name="province" required lay-verify="required" placeholder="请输入省份" autocomplete="off" class="layui-input" value="{{city.provincename}}"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">城市</label> <div class="layui-input-block"> <input type="text" name="city" required lay-verify="required" placeholder="请输入城市名称" autocomplete="off" class="layui-input" value="{{city.cityname}}"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">人数</label> <div class="layui-input-block"> <input type="number" name="number" required lay-verify="required" placeholder="请输入人数" autocomplete="off" class="layui-input" value="{{city.usernumber}}"> </div> </div> <div class="layui-form-item"> <div class="layui-input-block"> <button class="layui-btn" lay-submit lay-filter="formDemo">立即提交</button> <button type="reset" class="layui-btn layui-btn-primary">重置</button> </div> </div> </form> </div></div><script src="/static/layui/layui.js"></script><script> //Demo layui.use('form', function () { var form = layui.form; });</script></body></html>
insert.html:


<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>增加</title> <link rel="stylesheet" href="/static/layui/css/layui.css"></head><body><div class="layui-main"> <div class="site-content"> <br><br> <h1 class="site-h1">添加信息</h1><br><br> <form class="layui-form" action="insert" method="post"> <div class="layui-form-item"> <label class="layui-form-label">省份</label> <div class="layui-input-block"> <input type="text" name="province" required lay-verify="required" placeholder="请输入省份" autocomplete="off" class="layui-input"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">城市</label> <div class="layui-input-block"> <input type="text" name="city" required lay-verify="required" placeholder="请输入城市" autocomplete="off" class="layui-input"> </div> </div> <div class="layui-form-item"> <label class="layui-form-label">用户数</label> <div class="layui-input-block"> <input type="number" name="number" required lay-verify="required" placeholder="请输入用户数量" autocomplete="off" class="layui-input"> </div> </div> <div class="layui-form-item"> <div class="layui-input-block"> <button class="layui-btn" lay-submit lay-filter="formDemo">立即提交</button> <button type="reset" class="layui-btn layui-btn-primary">重置</button> </div> </div> </form> </div></div><script src="/static/layui/layui.js"></script><script> layui.use('form', function () { var form = layui.form; });</script></body></html>


重新运行项目


可以看到页面的颜值已经比之前没加任何样式提升了很多:







将网站发布到公网




配置环境


选择一台云主机,在云主机上配置好Python环境和MySQL环境。





部署服务


使用 nohup 命令可以后台部署python服务:


nohup python app.py &
然后使用exit命令退出 linux 的连接





购买域名


在公网的机器上部署好的服务器,现在还只能通过公网访问,要想通过域名能访问网站,还需要设置域名解析。

要给 web服务配置上域名,还需要到服务商网站购买域名,例如:阿里云、腾讯云等等。





域名备案


购买了域名之后无法直接使用,需要进行域名备案,同样在服务商那里备案即可。





域名接下


备案之后的域名就可以使用了,

使用域名解析,将指定域名解析到服务器的公网ip上,就可以通过这个域名来访问web服务器。





反向代理


域名解析完成之后,还需要做的工作是反向代理。

使用 nginx 服务器可以作为域名代理服务。

通过这几个步骤就可以让你的web服务成为面向互联网的web服务啦。

可以参考的最简单 nginx 配置文件配置如下:

这个代表将 http://flask.codejiaonang.com 域名,映射到本地web服务器的8848端口。


server {listen 80;autoindex on;server_name flask.codejiaonang.com;access_log /usr/local/nginx/logs/access.log combined;location / { proxy_pass http://127.0.0.1:8848/; }}


总结




网站项目开发的基本模式


通过Flask快速入门,我们可以将网站项目开发的基本模式总结为下图:





以 Flask 项目为例,Flask作为Web框架,它的作用主要是为了开发Web应用程序。

一个Web应用程序包含了三个部分,前端,服务端,数据库。





这个项目的线索


如果你也想让你的网站成为一个像那些商业级网站一样面向整个互联网的话。

可以按照下列线索,从购买服务器到购买域名,最后通过将域名与服务器和服务器中部署的网站相关联,一步一步来完成,当然其中会遇到很多困难和挑战和很多一时半会无法解决的错误,但是当你自己通过查找资料,解决问题,最终能把网站部署成功,你会发现这些知识都自然而然的融入到自己的知识体系中了。





关键词:入门

74
73
25
news

版权所有© 亿企邦 1997-2025 保留一切法律许可权利。

为了最佳展示效果,本站不支持IE9及以下版本的浏览器,建议您使用谷歌Chrome浏览器。 点击下载Chrome浏览器
关闭