Flask框架学习小总结

Flask框架学习小总结

2023年7月21日发(作者:)

Flask框架学习⼩总结区分Flask和

①Flask⾃由、灵活,可扩展性强,第三⽅库的选择⾯⼴,开发时可以结合⾃⼰最喜欢⽤的轮⼦,也能结合最流⾏最强⼤的Python库 ②⼊门简单,即便没有多少web开发经验,也能很快做出⽹站 ③⾮常适⽤于⼩型⽹站 ④⾮常适⽤于开发web服务的API ⑤开发⼤型⽹站⽆压⼒,但代码架构需要⾃⼰设计,开发成本取决于开发者的能⼒和经验 ⑥各⽅⾯性能均等于或优于Django

⑦Django⾃带的或第三⽅的好评如潮的功能,Flask上总会找到与之类似第三⽅库 ⑧Flask与关系型数据库的配合使⽤不弱于Django,⽽其与NoSQL数据库的配合远远优于 ①Django太重了,除了web框架,⾃带ORM和模板引擎,灵活和⾃由度不够⾼ ②Django能开发⼩应⽤,但总会有“杀鸡焉⽤⽜⼑”的感觉 ③Django的⾃带ORM⾮常优秀,综合评价略⾼于SQLAlchemy ④Django⾃带的模板引擎简单好⽤,但其强⼤程度和综合评价略低于Jinja ⑤Django⾃带ORM也使Django与关系型数据库耦合度过⾼,如果想使⽤MongoDB等NoSQL数据,需要选取合适的第三⽅库,且总感觉Django+SQL才是天⽣⼀对的搭配 ⑥Django⾮常适合企业级⽹站的开发:快速、靠谱、稳定 ⑦Django是Python web框架的先驱,⽤户多,第三⽅库最丰富,最好的Python库,如果不能直接⽤到Django中,也⼀定能找到与之对应的移植 ⑧Django上⼿也⽐较容易,开发⽂档详细、完善,相关资料丰富Flask开发环境搭建s下开发环境搭建 ①安装Python

②安装pip ③使⽤pip安装Flaskpip install flask2. Linux下开发环境搭建(Ubuntu 16.04 64) ①系统⾃带Python

②安装pip:sudo apt-get install python-pip ③使⽤pip安装Flask :pip install flask3. 配置基于Vim的Python开发环境(插件) ①Vundle ②YouCompleteMe ③NERDTree ④Vim-Jinja2-Syntax在 Flask 中的 "Hello, World"1.使⽤pycharm创建flask项⽬后会⾃动⽣成以下⽬录├─├─static└─的代码from flask import Flaskapp = Flask(__name__)@('/')def hello_world(): return 'Hello World!'

if __name__ == '__main__':()3.在浏览器输⼊127.0.0.1:5000后,即可在⽹页上出现"Hello World"的字样路由1.在上⾯的例⼦⾥可以看到路由的使⽤。如果了解Python另⼀款Web框架Django的话,我觉得应该对路由很熟悉,在Django⾥使⽤的是url来正则匹配当前路径,⽽Flask中路由是通过使⽤装饰器来设置@('/')def index(): return 'Index Page'@('/hello')def hello(): return 'Hello, World'2.路径变量 如果希望获取/blog/1这样的路径参数,就需要使⽤路径变量。路径变量的语法是/path/。在路径变量前还可以使⽤可选的转换器,有以下⼏种转换器转换器stringintfloatpathanyuuid作⽤默认选项,接受除了斜杠之外的字符串接受整数接受浮点数和string类似,不过可以接受带斜杠的字符串匹配任何⼀种转换器接受UUID字符串3.构造URL 在Web程序中常常需要获取某个页⾯的URL,在Flask中需要使⽤url_for('⽅法名')来构造对应⽅法的URL。下⾯是Flask官⽅的例⼦>>> from flask import Flask, url_for>>> app = Flask(__name__)>>> @('/')... def index(): >>> @('/login')... def login(): >>> @('/user/')... def profile(username): >>> with _request_context():... print url_for('index')... print url_for('login')... print url_for('login', next='/')... print url_for('profile', username='John Doe')...//login/login?next=//user/John%⽅法 如果需要处理具体的HTTP⽅法,在Flask中也很容易,使⽤route装饰器的methods参数设置即可from flask import request@('/login', methods=['GET', 'POST'])def login(): if == 'POST': do_the_login() else: show_the_login_form()5.静态⽂件 Web程序中常常需要处理静态⽂件,在Flask中需要使⽤url_for函数并指定static端点名和⽂件名。在下⾯的例⼦中,实际的⽂件应放在static/⽂件夹下Flask的模板功能1.模板功能与Django是⼀样的,所以不需要很长时间就能弄懂模板之时,默认情况下,⽂件需要放在templates⽂件夹下

hello {{ _name }}

2.新的模板功能 ①编写⼀个模拟登录的视图函数@('/query_user/')def query_user(user = None): return render_template("user_",user=user) ②为了渲染模板,必须从 Flask 框架中导⼊⼀个名为 render_template 的新函数。此函数需要传⼊模板名以及⼀些模板变量列表,返回⼀个所有变量被替换的渲染的模板 ③在内部,render_template 调⽤了 Jinja2 模板引擎,Jinja2 模板引擎是 Flask 框架的⼀部分。Jinja2 会把模板参数提供的相应的值替换了 {{…}} 块3.模板中控制语句 Jinja2 模板同样⽀持控制语句,像在 {%…%} 块中。在模板中添加⼀个 if 声明(⽂件templates/) {% if user %} hello {{ _name }}{% else %} no this user{% endif %}4.模板中的循环语句 ①为了表⽰⽤户的⽂章,这⾥使⽤了列表,其中每⼀个元素包含 author 和 body 字段。当使⽤真正的数据库的时候,会保留这些字段的名称,因此在设计以及测试模板的时候尽管使⽤的是假冒的对象,但不必担⼼迁移到数据库上更新模板def index(): user = { 'nickname': 'Miguel' }

posts = [

{ 'author': { 'nickname': 'John' }, 'body': 'Beautiful day in Portland!' }, { 'author': { 'nickname': 'Susan' }, 'body': 'The Avengers movie was so cool!' } ] return render_template("", title = 'Home', user = user, posts = posts) ②在模板这⼀⽅⾯,还有⼀个新问题。列表中可能有许多元素,多少篇⽂章被展⽰将取决于视图函数。模板不会假设有多少⽂章,因此它必须准备渲染视图传送的⽂章数量 ③因此可以使⽤ for 来做到这⼀点(⽂件templates/) {% if title %} {{title}} {% else %} microblog {% endif %}

Hi, {{me}}!

{% for post in posts %}

{{me}} says: {{}}

{% endfor %} Flask的模板继承1.可以利⽤ Jinja2 的模板继承的特点,这允许我们把所有模板公共的部分移除出页⾯的布局,接着把它们放在⼀个基础模板中,所有使⽤它的模板可以导⼊该基础模板2.所以定义⼀个基础模板,该模板包含导航栏以及上⾯谈论的标题(⽂件templates/),这与Django的模板继承也是⼀回事 ①在这个模板中,我们使⽤ block 控制语句来定义派⽣模板可以插⼊的地⽅,块被赋予唯⼀的名字

Header 蒋振飞的博客

{% block content %}{% endblock %}

Footer JzfBlog

②接着现在剩下的就是修改我们的 模板继承⾃ (⽂件templates/),注意:继承的时候⼀定要加上双引号{% extends "" %}{% block content %}

这是第⼀页

{% endblock %}处理请求 在 Flask 中获取请求参数需要使⽤request等⼏个全局对象,但是这⼏个全局对象⽐较特殊,它们是 Context Locals ,其实就是 Web上下⽂中局部变量的代理。虽然我们在程序中使⽤的是全局变量,但是对于每个请求作⽤域,它们都是互不相同的变量。理解了这⼀点,后⾯就⾮常简单了t 对象 简单做⼀个登录的样例

Hello Login

<--!⽤于获取flashed的内容-->

{{ get_flashed_messages()[0] }}

那么传到了login视图中,就需要导⼊request对象来接收这个表单@('/login', methods=['POST'])def login(): form = username = ('username') password = ('password') if not username: # ⽤户名为空 flash("please input username") return render_template("")

if not password: # 密码为空 flash("please input password") return render_template("") if username == 'flask' and password == 'mysql': # ⽤户名与密码等于设定值 flash("login success") return render_template("") else: # ⽤户名与密码设定值不符 flash("username or password is wrong") return render_template("")2.⽂件上传 利⽤Flask也可以⽅便的获取表单中上传的⽂件,只需要利⽤ request 的files属性即可,这也是⼀个字典,包含了被上传的⽂件。如果想获取上传的⽂件名,可以使⽤filename属性,不过需要注意这个属性可以被客户端更改,所以并不可靠。更好的办法是利⽤werkzeug提供的secure_filename⽅法来获取安全的⽂件名from flask import requestfrom import secure_filename@('/upload', methods=['GET', 'POST'])def upload_file(): if == 'POST': f = ['the_file'] ('/var/www/uploads/' + secure_filename(me))s Flask也可以⽅便的处理Cookie。使⽤⽅法很简单,直接看官⽅的例⼦就⾏了。下⾯的例⼦是如何获取cookiefrom flask import request@('/')def index(): username = ('username') # 使⽤ (key) 代替 cookies[key] 避免 # 得到 KeyError 如果cookie不存在 如果需要发送cookie给客户端,参考下⾯的例⼦。from flask import make_response@('/')def index(): resp = make_response(render_template(...)) _cookie('username', 'the username') return resp4.重定向和错误 redirect和abort函数⽤于重定向和返回错误页⾯from flask import abort, redirect, url_for@('/')def index(): return redirect(url_for('login'))@('/login')def login(): abort(401) this_is_never_executed() 默认的错误页⾯是⼀个空页⾯,如果需要⾃定义错误页⾯,可以使⽤errorhandler装饰器。from flask import render_template@andler(404)def page_not_found(error): return render_template('page_not_'), 4045.响应处理 默认情况下,Flask会根据函数的返回值⾃动决定如何处理响应:如果返回值是响应对象,则直接传递给客户端;如果返回值是字符串,那么就会将字符串转换为合适的响应对象。我们也可以⾃⼰决定如何设置响应对象,⽅法也很简单,使⽤make_response函数即可@andler(404)def not_found(error): resp = make_response(render_template(''), 404) s['X-Something'] = 'A value' return ns 我们可以使⽤全局对象session来管理⽤户会话。Sesison 是建⽴在 Cookie 技术上的,不过在 Flask 中,还可以为 Session 指定密钥,这样存储在 Cookie 中的信息就会被加密,从⽽更加安全。直接看 Flask 官⽅的例⼦from flask import Flask, session, redirect, url_for, escape, requestapp = Flask(__name__)@('/')def index(): if 'username' in session: return 'Logged in as %s' % escape(session['username']) return 'You are not logged in'@('/login', methods=['GET', 'POST'])def login(): if == 'POST': session['username'] = ['username'] return redirect(url_for('index')) return '''

'''@('/logout')def logout(): # remove the username from the session if it's there ('username', None) return redirect(url_for('index'))# set the secret key. keep this really secret:_key = 'A0Zr98j/3yX R~XHH!jmN]LWX/,?RT'web 表单1.配置 ①为了能够处理 web 表单,我们将使⽤ Flask-WTF ,该扩展封装了 WTForms 并且恰当地集成进 Flask 中 ②许多 Flask 扩展需要⼤量的配置,因此我们将要在项⽬的根⽬录下创建⼀个配置⽂件以⾄于容易被编辑。这就是我们将要开始的(⽂件):CSRF_ENABLED = TrueSECRET_KEY = 'you-will-never-guess' ③Flaks-WTF 扩展只需要两个配置。 CSRF_ENABLED 配置是为了激活 跨站点请求伪造 保护。在⼤多数情况下,你需要激活该配置使得你的应⽤程序更安全些 ④SECRET_KEY 配置仅仅当 CSRF 激活的时候才需要,它是⽤来建⽴⼀个加密的令牌,⽤于验证⼀个表单。当编写⾃⼰的应⽤程序的时候,需要设置很难被猜测到密钥 ⑤既然有了配置⽂件,我们需要告诉 Flask 去读取以及使⽤它。我们可以在 Flask 应⽤程序对象被创建后去做,⽅式如下(⽂件 )from flask import Flaskapp = Flask(__name__)_object('config')2.⽤户登录表单 ①在 Flask-WTF 中,表单是表⽰成对象,Form 类的⼦类。⼀个表单⼦类简单地把表单的域定义成类的变量 ②编写第⼀个表单(⽂件):from wtforms import Form, TextField, PasswordField, validatorsclass LoginForm(Form): username = TextField("username", [ed()]) password = PasswordField("password", [ed()]) ③导⼊ Form 类,接着导⼊两个们需要的字段类,TextField 和 PasswordField ④ed()验证器只是简单地检查相应域提交的数据是否是空3.表单模板 ①登录的模板(⽂件templates/){% extends "" %}{% block content %}

User Management

{% if message %} {{message}} {% endif %}
{{_tag()}}

Username :{{me}}
Password :{{rd}}

{% endblock %} ②重⽤了 模板通过 extends 模板继承声明语句,以确保所有⽹页的布局⼀致性 ③_tag() 模板参数将被替换为⼀个隐藏字段,⽤来是实现在配置中激活的 CSRF 保护。如果已经激活了 CSRF,这个字段需要出现在你所有的表单中 ④表单中实际的字段也将会被表单对象渲染,必须在字段应该被插⼊的地⽅指明⼀个 {{_name}} 模板参数。某些字段是可以带参数的 ⑤没有在表单中定义提交按钮,因为提交字段实际并不携带数据因此没有必要在表单类中定义4.表单视图 ①新的视图函数(⽂件):from flask import render_template, flash, redirectfrom .forms import LoginForm# index view function suppressed for brevity@('/login', methods = ['GET', 'POST'])def login(): form = LoginForm() return render_template('', form=form)5.接收表单数据@("/user", methods=['GET', 'POST'])def login(): myForm = LoginForm() if == 'POST': # if te_on_submit(): if == "flask" and == "mysql" and te(): return redirect("") else: message="Login Failed" return render_template('', message=message, form=myForm) return render_template('', form=myForm) ②validate_on_submit ⽅法做了所有表单处理⼯作。当表单正在展⽰给⽤户的时候调⽤它,它会返回 False.

③如果 validate_on_submit 在表单提交请求中被调⽤,它将会收集所有的数据,对字段进⾏验证,如果所有的事情都通过的话,它将会返回 True,表⽰数据都是合法的。这就是说明数据是安全的,并且被应⽤程序给接受了 ④如果⾄少⼀个字段验证失败的话,它将会返回 False,接着表单会重新呈现给⽤户,这也将给⽤户⼀次机会去修改错误。我们将会看到当验证失败后如何显⽰错误信息 ⑤当 validate_on_submit 返回 True,我们的登录视图函数调⽤了两个新的函数,导⼊⾃ Flask。flash 函数是⼀种快速的⽅式下呈现给⽤户的页⾯上显⽰⼀个消息。在我们的例⼦中,我将会使⽤它来调试,因为我们⽬前还不具备⽤户登录的必备的基础设施,相反我们将会⽤它来显⽰提交的数据。flash 函数在⽣产服务器上也是⼗分有作⽤的,⽤来提供反馈给⽤户有关的⾏动使⽤Mysql数据库1.连接Mysql数据库 在项⽬中创建⼀个⽂件,这是通过对sql语句直接针对数据库的操作# 注:py3使⽤的是pymysql,py2使⽤mysqldbimport pymysqlconn = t(host='localhost', user='root', password="5201314mysql", database='test')cur = ()def addUser(username, password): """ 添加⽤户 :param username: ⽤户名 :param password: 密码 """ insert_sql = "insert into user(username, password) values('%s', '%s')" % (username, password) # 提交sql语句 e(insert_sql)

# 保存 ()def isExisted(username, password): """ 判断⽤户是否已经存在 :param username: ⽤户名 :param password: 密码 :return: True or False """ sql = "select * from user where username='%s' and password='%s'" % (username, password) # 提交sql语句 e(sql) # 获取查询结果 result = ll() if len(result): return True else: return False2.在项⽬中创建,⽤于登录与注册的表单from wtforms import Form, TextField, PasswordField, validatorsclass LoginForm(Form): """ 登录表单 """ username = TextField('username', [ed()]) password = PasswordField('password', [ed()])class RegisterForm(Form): """注册表单""" username = TextField('username', [ed()]) password = PasswordField('password', [ed()]) password_again = PasswordField('password', [ed()])3.新建⼀个⽂件,⽤户对视图进⾏处理from flask import Flask, render_template, request, redirect, flashfrom forms import *from db import *app = Flask(__name__)_object('config')@('/login', methods=['GET', 'POST'])def login(): """ 登录 :return: 登录模板视图 """ # 先创建⼀个登录的表单 login_form = LoginForm() if == 'POST': # if login_ == 'flask' and login_ == 'mysql' and login_te(): # 如果数据库存在这样的⽤户名与密码 if isExisted(login_, login_) and login_te(): # 返回到我的主页 return redirect('') else: message = 'Login False' # 不存在或密码不正确就返回Login False的错误信息 return render_template('', form=login_form, message=message) return render_template('', form=login_form)@('/register', methods=['GET', 'POST'])def register(): """ 注册 :return: 注册模板视图 """ # 创建注册表单 register_form = RegisterForm() if == 'POST': # 判断第⼀次输⼊密码与第⼆次输⼊密码是否⼀致 if register_ != register_rd_: message = "两次密码输⼊不⼀致" # 返回错误信息 return render_template('', form=register_form, message=message) else: if not isExisted(register_, register_): # 如果数据库没有这样的⽤户,就在数据库新增⼀个 # addUser是的操作数据库添加⽤户的函数 addUser(register_, register_) return redirect('') message = "账号已存在,请重新注册" # 如果数据库已经存在这个⽤户,就返回已存在的信息 return render_template('', form=register_form, message=message) return render_template('', form=register_form)if __name__ == "__main__": ()4.在templates模板⽂件夹下创建

欢迎登录

{{ message }}
{# {{_tag()}}#} {{ me }} {{ rd }}
5.在templates模板⽂件夹下创建

欢迎注册

{{ message }}
{# {{_tag()}}#} {{ me }} {{ rd }} {{ rd_again }}
数据库映射1.何谓对象关系映射 对象关系映射,即Object Relational Mapping,简称ORM,是⼀种程序设计技术,⽤于实现⾯向对象程序设计⾥不同类型之间系统的数据之间的转换2. 为什么要使⽤ORM ①避免和复杂的sql语句打交道 ②提⾼开发效率,也更容易理解 ③⽅便形成统⼀风格的代码 ④带来⼀些安全性上的提升3.还有⼀个重要的知识点,就是数据库注⼊,通过数据库映射就能有效地避免这⼀现象 百度百科对数据库映射的解释是:⽤户可以提交⼀段数据库查询代码,根据程序返回的结果,获得某些他想得知的数据,这就是所谓的SQL Injection,即SQL注⼊ 根据理解,简单的⽤⼀个例⼦解释⼀下。⽐如之前的⽤户注册和登录,我在中写了⼀个判断⽤户是否存在数据库的⽅法,也就是isExisted⽅法,⾥⾯使⽤了sql = "select * from user where username='%s' and password='%s'" % (username, password) 其实上⾯这段查询语句还可以按下⾯这样写,不过这就会出现问题了,很容易发⽣sql注⼊的现象sql = 'select * from user where username=' + username + ' and password = ' + password 假设我在登录的时候输⼊username为1,让password 输⼊ 1 or 1 = 1 ,sql查询语句就会变成这样select * from user where username = 1 and password =1 or 1 = 1 不知道发现没有,后⾯有⼀个or 1 =1,那这就是 ⼀定成⽴的条件了!也就是数据库⼀定可以select到,即使没有1这个⽤户名,也能被登录了(亲测),所以不能使⽤拼接字符串的⽅法来实现查询功能 4.使⽤对象关系映射的优点与缺点 ①系统消耗较⼤ ②处理较复杂的查找条件时,使⽤ORM不够灵活 ③占⽤内存⽐较⼤ 中的ORM Flask-SQLAlchemy:基于SQLAlychemy的Flask扩展 安装配置Flask-SQLAlchemypip install flask-sqlalchemy 在shell终端的python环境测试⼀下导⼊这个包from hemy import SQLAlchemy 我的这⾥仍然会出现⼀个No module named ''的错误,查了⼀下,解决需要改变⼀种导⼊⽅式from flask_sqlalchemy import SQLAlchemy6.创建⽂件,⽤来定义数据库模型# flask import Flask# from hemy import SQLAlchemyfrom flask_sqlalchemy import SQLAlchemyapp = Flask(__name__)# 如果数据库没有密码,直接mysql://root@mysql@localhost/test就可以了['SQLALCHEMY_DATABASE_URI'] = 'mysql://root:5201314mysql@localhost/test'db = SQLAlchemy(app)class User(): id = (r,primary_key=True) username = ((32),unique=True) password = ((32)) def __init__(self,username,password): me = username rd = password def add(self): """ 增加⽤户 :return: 成功返回0,失败返回错误信息 """ try: (self) () return except Exception,e: ck() return e finally: return 0 def isExisted(self): """ 判断⽤户是否存在 :return: 存在返回1,不存在返回0 """ # _by来筛选条件 temUser=_by(username=me,password=rd).first() if temUser is None: return 0 else: return 1 所以现在,如果满⾜创建⽤户的条件就改为u = User(register_,register_)() 满⾜登录条件u = User(login_,login_)if (ted()): return redirect("")

发布者:admin,转转请注明出处:http://www.yc00.com/news/1689899364a293275.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信