Python-flask学习笔记
Python虚拟环境安装
Python激活虚拟环境
1
| virtualenv [virtualenv-name]
|
pip安装flask
使用pycharm创建新项目
程序基本结构
初始化Flask对象
传递一个参数__name__
,参数作用是:
1.方便flask框架去寻找资源
2.方便flask插件比如Flask-Sqlalchemy出现错误时候好去寻找问题所在
1 2
| from flask import Flask app = Flask(__name__)
|
创建路由与视图函数
1 2 3
| @app.route('/') def hello_world(): return 'Hello World!'
|
@app.route是一个装饰器,以@开头,并且在函数的上面,说明是装饰器
这个装饰器的作用,是做一个url与视图函数的映射,处理函数与url之间的映射成为路由
127.0.0.1:5000/ -> 去请求hello_world这个视图函数,然后将结果返回给服务器
启动服务器
1 2
| if __name__ == '__main__': app.run()
|
app.run()作用是启动一个应用服务器,来接受用户的请求
完整程序
1 2 3 4 5 6 7 8 9 10
| from flask import Flask
app = Flask(__name__)
@app.route('/') def hello_world(): return 'Hello World!'
if __name__ == '__main__': app.run()
|
设置debug模式
1.在app.run()中传入一个关键字参数debug,app.run(debug=True),就设置当前项目为debug模式
2.debug模式的两大功能:
(1)当程序出现问题的时候,可以在页面中看到错误信息和出错的位置。
(2)只要修改了项目中的python文件,程序会自动加载,不需要手动重新启动服务器
url传参数
1.参数的作用:可以在相同的URL,但是指定不同的参数,来加载不同的数据
2.在flask中使用参数
1 2 3
| @app.route('/article/<id>') def article(id): return u'您请求的参数是: %s '%id
|
参数需要放在两个尖括号中
视图函数中需要放和url中的参数同名的参数
反转url
1.什么叫做反转URL:从视图函数到url的转换叫做反转url
2.反转url的用处:
(1)在页面重定向的时候,会使用url反转
(2)在模板中,也会使用url反转
3.例子
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
|
from flask import Flask,url_for
app = Flask(__name__)
@app.route('/') def hello_world(): print url_for('my_list') print url_for('article',id=1000) return 'Hello'
@app.route('/list/') def my_list(): return 'list'
@app.route('/article/<id>') def article(id): return u'您请求的参数是: %s '%id
if __name__ == '__main__': app.run(debug=True)
|
页面跳转和重定向
1.用处:在用户访问一些需要登录的页面的时候,如果用户没有登录,那么可以让他重定向到登录页面
2.代码实现:
1 2
| from flask import redirect,url_for redirect(url_for('login'))
|
3.例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
from flask import Flask,redirect,url_for
app = Flask(__name__)
@app.route('/') def index(): login_url = url_for('login') return redirect(login_url) return u'这是首页'
@app.route('/login/') def login(): return u'这是登录页面'
if __name__ == '__main__': app.run(debug=True)
|
访问127.0.0.1:5000/自动跳转到127.0.0.1:5000/login/
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
from flask import Flask,redirect,url_for
app = Flask(__name__)
@app.route('/') def index(): login_url = url_for('login') return redirect(login_url) return u'这是首页'
@app.route('/login/') def login(): return u'这是登录页面'
@app.route('/question/<is_login>') def question(is_login): if is_login == '1': return u'这是发布问答的页面' else: return redirect(url_for('login'))
if __name__ == '__main__': app.run(debug=True)
|
如果我们访问127.0.0.1:5000/question/0则自动重定向到登录页面
Flask渲染jinja2模板和传参
渲染模板
1.模板放在templates文件夹下
2.从flask中导入render_template函数
3.在视图函数中,使用render_template函数,渲染模板。注意:只需要填写模板的名字,不需要填写templates文件夹
模板传参
1.如果只有一个或者少量参数,直接在render_template函数中添加关键字就可以了
2.如果有多个参数的时候,那么可以先把所有的参数放在字典中,然后在render_template中,使用两个星号,把字典转换成关键参数传递进去,这样代码更方便管理和使用
3.在模板中,如果要使用一个变量,语法是:
例子:
index.html中内容
渲染模板代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
|
from flask import Flask,render_template
app = Flask(__name__)
@app.route('/') def index(): context = { 'username':u'知了课堂', 'gender':u'男', 'age':18 } return render_template('index.html',**context)
if __name__ == '__main__': app.run(debug=True)
|
模板中访问属性和字典
访问模型中的属性或者是字典,可以通过的形式,或者是使用
例子:
index.html
1 2 3 4 5 6 7 8 9 10 11 12
| 这是HTML文件中出现的文字 <p>用户名:{{ username }}</p> <p>性别:{{ gender }}</p> <p>年龄:{{ age }}</p>
<hr> <p>名字:{{ person.name }}</p> <p>年龄:{{ person.age }}</p>
<hr> <p>百度:{{ websites.baidu }}</p> <p>谷歌:{{ websites.google }}</p>
|
python代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
|
from flask import Flask,render_template
app = Flask(__name__)
@app.route('/') def index(): class Person(object): name = 'somnus' age = 18
p = Person()
context = { 'username':'somnus', 'gender':u'男', 'age':18, 'person':p, 'websites':{ 'baidu':'www.baidu.com', 'google':'www.google.com' } } return render_template('index.html',**context)
if __name__ == '__main__': app.run(debug=True)
|
执行结果:
if判断
1.语法:
1 2 3
| {% if 判断条件 %} {% else %} {% endif %}
|
2.if的使用,可以和python中相差无几
3.例子
if.html
1 2 3 4 5 6 7
| {% if user %} <a href="#">{{ user.username }}</a> <a href="#">注销</a> {% else %} <a href="#">登录</a> <a href="#">注册</a> {% endif %}
|
python代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
|
from flask import Flask,render_template
app = Flask(__name__)
@app.route('/<is_login>/') def index(is_login): if is_login == '1': user = { 'username':'somnus', 'age':18 } return render_template('if.html',user=user) else: return render_template('if.html')
if __name__ == '__main__': app.run(debug=True)
|
for循环遍历列表和字典
1.字典的遍历,语法和python一样,可以使用items(),keys(),values(),iteritems(),iterkeys(),itervalues()
1 2 3
| {% for k,v in user.items() %} <p>{{ k }}:{{ v }}</p> {% endfor %}
|
2.例子
for.html
1 2 3
| {% for k,v in user.items() %} <p>{{ k }}:{{ v }}</p> {% endfor %}
|
python代码
1 2 3 4 5 6 7 8 9 10 11 12 13
|
from flask import Flask,render_template
app = Flask(__name__)
@app.route('/') def index(): user = { 'username':'somnus', 'age':18 } return render_template('for.html',user=user)
|
执行结果:
3.列表的遍历:语法和python一样
1 2 3
| {% for list in lists %} <p>{{ website }}</p> {% endfor %}
|
过滤器
1.介绍和语法:
(1)介绍:过滤器可以处理变量,把原始的变量经过处理后再展示出来
(2)语法:
1
| {{ avatar|default('xxx') }}
|
2.default过滤器:如果当前变量不存在,这时候可以指定默认值
3.length过滤器:求列表或者字符串或者字典或者元组的长度
继承和block
1.继承的作用和语法:
(1)作用:可以把一些公共的代码放在父模板中,避免每个模板写同样的代码
(2)语法:
1
| {% extends 'base.html' %}
|
2.block实现:
(1)作用:可以让子模板实现自己的一些需求,父模板需要提前定义好
(2)注意点:子模板中的代码,必须放在block块中
3.例子
模板base.html
1 2 3 4 5 6 7 8 9 10 11 12
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> 这是一个模板 {% block main %} {% endblock %} </body> </html>
|
继承block.html
1 2 3 4
| {% extends 'base.html' %} {% block main %} 这是一个子模板 {% endblock %}
|
url链接
使用url_for(视图函数名称)可以反转成url
加载静态文件
1.语法:
1
| url_for('static',filename='路径')
|
2.静态文件,flask会从static文件夹开始寻找,所以不用再写static这个路径
3.可以加载css文件,可以加载js文件,还有image文件
Mysql-python中间件安装
https://www.lfd.uci.edu/~gohlke/pythonlibs/#mysql-python
flask-sqlalchemy安装与使用
1.安装
1
| pip install flask-sqlalchemy
|
2.使用
(1)使用flask_sqlalchemy中的SQLAlchemy进行初始化:
1 2 3
| from flask_sqlalchemy import SQLAlchemy app = Flask(__name__) db = SQLAlchemy(app)
|
(2)设置配置信息:在config.py文件中添加以下配置信息:
1 2 3 4 5 6 7 8 9 10 11
| DIALECT = 'mysql' DRIVER = 'mysqldb' USERNAME = 'root' PASSWORD = 'root' HOST = '127.0.0.1' PORT = '3306' DATABASE = 'db_demo1'
SQLALCHEMY_DATABASE_URI = "{}+{}://{}:{}@{}:{}/{}?charset=utf8".format(DIALECT,DRIVER,USERNAME,PASSWORD,HOST,PORT,DATABASE) SQLALCHEMY_TRACK_MODIFICATIONS = False
|
(3)在主app文件中,添加配置文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| from flask import Flask from flask_sqlalchemy import SQLAlchemy import config
app = Flask(__name__) app.config.from_object(config) db = SQLAlchemy(app)
db.create_all()
@app.route('/') def index(): return ''
if __name__ == '__main__': app.run(debug=True)
|
(4)测试有没有问题报错,如无,则成功连接
使用Flask-SQLAlchemy创建模型与表的映射
1.模型需要继承自db.Model,然后需要映射到表中的属性,必须写成’db.Column’的数据类型
2.数据类型:db.Integer代表的是整型,db.String代表的是varchar,需要指定最长的长度,db.Text代表的是text
3.其他参数:primary_key代表的是将这个字段设置为主键,autoincrement代表的是这个主键为自增长的,nullable代表的是这个字段是否可以为空,可以将这个值设置为False,在数据库中,这个值就不能为空了
4.最后需要调用db.create_all来将模型真正创建到数据库中
例子:
config.py
1 2 3 4 5 6 7 8 9 10
| DIALECT = 'mysql' DRIVER = 'mysqldb' USERNAME = 'root' PASSWORD = 'root' HOST = '127.0.0.1' PORT = '3306' DATABASE = 'db_demo2'
SQLALCHEMY_DATABASE_URI = "{}+{}://{}:{}@{}:{}/{}?charset=utf8".format(DIALECT,DRIVER,USERNAME,PASSWORD,HOST,PORT,DATABASE) SQLALCHEMY_TRACK_MODIFICATIONS = False
|
创建table执行的sql语句:
1 2 3 4 5
| create table article( id int primary key auto_increment, title varchar(100) not null, content text not null, )
|
db_demo2.py
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| from flask import Flask from flask_sqlalchemy import SQLAlchemy import config
app = Flask(__name__) app.config.from_object(config)
db = SQLAlchemy(app)
class Article(db.Model): __tablename__ = 'article' id = db.Column(db.Integer,primary_key=True,autoincrement=True) title = db.Column(db.String(100),nullable=False) content = db.Column(db.Text,nullable=False)
db.create_all()
@app.route('/') def index(): return 'index'
if __name__ == '__main__': app.run(debug=True)
|
Flask-SQLAlchemy数据的增,删,改,查
1.增:
1 2 3
| article1 = Article(title='aaa',content='bbb') db.session.add(article1) db.session.commit()
|
2.查:
1 2 3
| article1 = Article.query.filter(Article.title == 'aaa').first() print 'title:%s' % article1.title print 'content:%s' % article1.content
|
3.改:
1 2 3 4 5 6
| article1 = Article.query.filter(Article.title == 'aaa').first()
article1.title = 'new title'
db.session.commit()
|
4.删:
1 2 3 4 5 6
| article1 = Article.query.filter(Article.content == 'bbb').first()
db.session.delete(article1)
db.session.commit()
|
flask中的session工作机制
1.flask中的session机制是:把敏感数据经过加密后放入session中,然后再把session存放到cookie中,下次请求的时候,再把浏览器发送过来的cookie中读取session,然后再从session中读取敏感数据,并进行解密,获取最终的用户数据
2.flask的这种session机制,可以节省服务器的开销,因为把所有的信息都存储到了客户端(浏览器)
3.安全是相对的,把session放到cookie中,经过加密,也是比较安全的
flask操作session
1.session的操作方式:
(1)使用session需要从flask中导入session,以后和session相关的操作都是通过这个变量来的
(2)使用session需要设置SECRET_KEY,作为加密用的,并且这个SECRET_KEY,如果每次服务器启动后都变化的话,那么之前的session就不能再通过当前这个SECRET_KEY就不能再进行解密了
(3)操作session的时候,跟操作字典是一样的
(4)添加session:session[‘username’]=’admin’
(5)删除:session.pop(‘username’)
(6)清除所有session:session.clear()
(7)获取session:session.get(‘username’)
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| from flask import Flask,session import os
app = Flask(__name__) app.config['SECRET_KEY'] = os.urandom(24)
@app.route('/') def index(): session['username'] = 'admin' return 'hello'
@app.route('/get/') def get(): return session.get('username')
@app.route('/delete/') def delete(): print session.get('username') session.pop('username') print session.get('username') return 'success'
|
2.设置session过期时间
(1)如果没有指定session的过期时间,那么默认浏览器关闭后就自动结束
(2)如果设置了session的permanent属性为True,那么过期时间是31天
(3)可以通过给app.config设置PERMANENT_SESSION_LIFETIME来更改过期时间,这个值的数据类型是datetime.timedelay类型
Flask实现GET和POST请求获取参数
1.get请求是通过flask.request.args来获取
2.post请求是通过flask.request.form来获取
3.post请求在模板中要注意几点:
(1)input标签中,要写name来标识这个value的key,方便后台获取
(2)在写form表单的时候,要指定method=’post’,并且要指定action=’/login/‘
实例:
实现页面跳转
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| from flask import Flask,render_template
app = Flask(__name__)
@app.route('/') def index(): return render_template('get_post_demo.html')
@app.route('/search/') def search(): return 'search'
@app.route('/login/') def login(): return 'login'
|
html代码:
1
| <a href="{{ url_for('search',q='hello') }}">跳转到搜索页面</a>
|
获取GET请求参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| from flask import Flask,render_template,request
app = Flask(__name__)
@app.route('/') def index(): return render_template('get_post_demo.html')
@app.route('/search/') def search(): q = request.args.get('q') return 'get:%s'%q
@app.route('/login/') def login(): return 'login'
|
获取POST请求参数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| from flask import Flask,render_template,request
app = Flask(__name__)
@app.route('/') def index(): return render_template('get_post_demo.html')
@app.route('/search/') def search(): q = request.args.get('q') return 'get:%s'%q
@app.route('/login/',methods=['GET','POST']) def login(): if request.method == 'GET': return render_template('login.html') elif request.method == 'POST': username = request.form.get('username') password = request.form.get('password') return 'username:%s password:%s'%(username,password)
|
html代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| <form action="{{ url_for('login') }}" method="post"> <table> <tbody> <tr> <td>用户名:</td> <td><input type="text" placeholder="请输入用户名" name="username"></td> </tr> <tr> <td>密码:</td> <td><input type="text" placeholder="请输入密码" name="password"></td> </tr> <tr> <td></td> <td><input type="submit" value="登录"></td> </tr> </tbody> </table> </form>
|
保存全局变量的g属性
g:global
1.g对象是专门用来保存用户的数据
2.g对象在一次请求中的所有的代码的地方,都是可以使用的
钩子函数(hook)
1.before_request:在请求之前执行的,即在视图函数执行之前执行的,这个函数只是一个装饰器,他可以把需要设置为钩子函数的代码放到视图函数执行之前来执行
示例代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39
|
from flask import Flask,render_template,request,session,g,redirect,url_for import os
app = Flask(__name__) app.config['SECRET_KEY'] = os.urandom(24)
@app.route('/') def index(): return render_template('get_post_demo.html')
@app.route('/login/',methods=['GET','POST']) def login(): if request.method == 'GET': return render_template('login.html') elif request.method == 'POST': username = request.form.get('username') password = request.form.get('password') if username == 'admin' and password == '123456': session['username'] = username return u'登录成功' else: return u'用户名或密码错误'
@app.route('/edit/') def edit(): if hasattr(g,'username'): return u'修改成功' else: return redirect(url_for('login'))
@app.before_request def before_request(): if session.get('username'): g.username = session.get('username')
if __name__ == '__main__': app.run(debug=True)
|
2.context_processor:
(1)上下文处理器应该返回一个字典,字典中的key会被模板中当成变量来渲染
(2)上下文处理器中返回的字典,在所有页面中都是可用的
示例代码:
1 2 3 4 5
| @app.context_processor def my_context_processor(): username = session.get('username') if username: return {'username':username}
|
视频学习地址:flask视频学习