收藏 分销(赏)

Flask之旅FlaskWeb开发基于Python的Web应用开发实战学习笔记.doc

上传人:Fis****915 文档编号:553941 上传时间:2023-12-07 格式:DOC 页数:27 大小:414KB
下载 相关 举报
Flask之旅FlaskWeb开发基于Python的Web应用开发实战学习笔记.doc_第1页
第1页 / 共27页
Flask之旅FlaskWeb开发基于Python的Web应用开发实战学习笔记.doc_第2页
第2页 / 共27页
Flask之旅FlaskWeb开发基于Python的Web应用开发实战学习笔记.doc_第3页
第3页 / 共27页
Flask之旅FlaskWeb开发基于Python的Web应用开发实战学习笔记.doc_第4页
第4页 / 共27页
Flask之旅FlaskWeb开发基于Python的Web应用开发实战学习笔记.doc_第5页
第5页 / 共27页
点击查看更多>>
资源描述

1、Flask之旅Flask Web开发:基于Python的Web应用开发实战学习笔记1 虚拟环境2016-6-8书上介绍了 virtualenv,每个venv都会拷贝一份packages到项目 /venv目录。plain view plain copy1.virtualenv venv 2.venvScriptsactivate.bat 3.(venv) $ pip freeze requirements.txt 4.(venv) $ pip install -r requirements.txt 5.pip list -outdated 6.pip install -upgarade 比较了一

2、下conda管理环境,可能conda更胜一筹:点击打开链接或者用 virtualenvwrapper: 点击打开链接plain view plain copy1.git tag 列出所有打tag的分支 2.git checkout 切换到tag 3.git reset -hard 不保留修改 .gitignore:指定哪些文件或目录不作同步,比如 ./venv/,*.pyc,数据库文件.sqlite3, .mysql推荐IDE: PyCharm 2016.1导入已有的virtualenv: File - Setting - Project Interprater - 选择项目目录下的/venv

3、/Python特点:- new Flask Project- jump between View funcion and Templates- Git2 基本结构初始化:python view plain copy1.# -*- coding: utf-8 -*- 2.from flask import Flask 3. app = Flask(_name_) Flask类的构造函数只有一个必须指定的参数,即程序主模块或包的名字。在大多数程序中,Python的_name_变量就是所需的值。Flask用这个参数决定程序的根目录,以便稍后能够找到相对于程序根目录的资源文件位置路由 (route)和

4、视图函数 (view function):定义路由的最简便方式,是使用程序实例提供的app.route修饰器,把修饰的函数注册为路由python view plain copy1.app.route(/) 2.def index(): 3. return Hello World! 修饰器是Python语言的标准特性,可以使用不同的方式修改函数的行为。惯常用法是使用修饰器把函数注册为事件的处理程序。动态路由:地址中可以包含可变部分,Flask支持在路由中使用int、float和path类型。path类型也是字符串,但不把斜线视作分隔符python view plain copy1.app.rou

5、te(/user/) 2.def user(name): 3. return Hello, %s! %name 4.app.route(/user/) # 不能有空格! 5.def . 默认端口是5000,可以改成其它的(flask_script.Manager也有此功能)# 有些端口不能用,查询已占用的端口:netstat -ano;netstat -aon|findstr 6000;tasklist|findstr ;taskkill /f /t /im XXX.exepython view plain copy1.app.run(debug=True, port=7777) 1.公认端口

6、(Well Known Ports):从0到1023,紧密绑定(binding)于一些服务。通常这些端口的通讯明确表明了某种服务协议。80端口实际上总是HTTP通讯。2.注册端口(Registered Ports):从1024到49151。它们松散地绑定于一些服务。这些端口同样用于许多其它目的。例如:许多系统处理动态端口从1024左右开始。3.动态和/或私有端口(Dynamic and/or Private Ports):从49152到65535。理论上,不应为服务分配这些端口。实际上,机器通常从1024起分配动态端口。请求-响应循环Context 上下文全局变量:current_app 程序

7、上下文 当前激活程序的程序实例g 程序上下文 处理请求时用作临时存储的对象。每次请求都会重设这个变量request 请求上下文 请求对象,封装了客户端发出的HTTP请求中的内容session 请求上下文 用户会话,用于存储请求之间需要“记住”的值的词典URL映射是URL和视图函数之间的对应关系。Flask使用app.route修饰器或者非修饰器形式的app.add_url_rule()生成映射。python view plain copy1.app.url_map 2.Map( index, 3.Rule /static/ (HEAD, OPTIONS, GET) - static, 4.Ru

8、le /user/ (HEAD, OPTIONS, GET) - user) HEAD、Options、GET是请求方法,由路由进行处理。Flask为每个路由都指定了请求方法,这样不同的请求方法发送到相同的URL上时,会使用不同的视图函数进行处理。HEAD和OPTIONS方法由Flask自动处理请求 Hook: 在请求钩子函数和视图函数之间共享数据一般使用上下文全局变量g1.before_first_request :注册一个函数,在处理第一个请求之前运行。2.before_request :注册一个函数,在每次请求之前运行。3.after_request :注册一个函数,如果没有未处理的异常

9、抛出,在每次请求之后运行。4.teardown_request :注册一个函数,即使有未处理的异常抛出,也在每次请求之后运行响应(视图函数返回)make_response()函数可接受13个参数 (html, 状态码,header)python view plain copy1.response = make_response(This document carries a cookie!, 200) 2.response.set_cookie(answer, 42) 3.return response 重定向的特殊响应类型,302:return redirect()特殊的响应由abort函数

10、生成,用于处理错误:abort(404)Flask扩展原书更正: Importing flask.ext.script is deprecated, use flask_script instead.3 模板 template业务逻辑和表现逻辑 要分开按功能分(模板不需要重用时),或按Division分(大部分模板需要重用时)Jinja2模板引擎模板是一个包含响应文本的文件,其中包含用占位变量.表示的动态部分,其具体值只在请求的上下文中才能知道。使用真实值替换变量,再返回最终得到的响应字符串,这一过程称为渲染。python view plain copy1.app.route(/user/)

11、2.def user(name): 3. return render_template(user.html, name=name) 模板变量Jinja2能识别所有类型的变量,甚至是一些复杂的类型,例如列表、字典和对象html view plain copy1.A value from a dictionary: mydictkey . 2.A value from a list: mylist3 . 3.A value from a list, with a variable index: mylistmyintvar . 4.A value from an objects method: m

12、yobj.somemethod() . 可以使用过滤器修改变量。千万别在不可信的值上使用safe过滤器,例如用户在表单中输入的文本html view plain copy1.Hello, name|capitalize 完整的过滤器列表safe 渲染值时不转义。默认情况下,出于安全考虑,Jinja2会转义所有变量capitalize 把值的首字母转换成大写,其他字母转换成小写lower 把值转换成小写形式upper 把值转换成大写形式title 把值中每个单词的首字母都转换成大写trim 把值的首尾空格去掉striptags 渲染之前把值中所有的HTML标签都删掉控制结构%.%,可用来改变模板

13、的渲染流程 if, for, macro, import, include需要在多处重复使用的模板代码片段可以写入单独的文件,再包含 %include common.html % 在所有模板中另一种重复使用代码的强大方式是模板继承,block标签定义的元素可在衍生模板中修改html view plain copy1. 2. 3. %block head % 4. %block title %endblock % - My Application 5. %endblock % 6. 7. 8. %block body % 9. %endblock % 10. 11. extends指令声明这个模

14、板衍生自base.html。在extends指令之后,基模板中的3个块被重新定义,模板引擎会将其插入适当的位置。注意新定义的head块,在基模板中其内容不是空的,所以使用super()获取原来的内容(向已经有内容的块中添加新内容)。html view plain copy1.%extends base.html % 2.%block title %Index%endblock % 3.%block head % 4. super() 5. 6. 7.%endblock % 8.%block body % 9. Hello, World! 10.%endblock % 使用Flask-Boots

15、trapBootstrap是客户端框架,因此不会直接涉及服务器。服务器需要做的只是提供引用了Bootstrap层 叠样式表(CSS)和JavaScript文 件的HTML响 应,并在HTML、CSS和JavaScript代码中实例化所需组件。这些操作最理想的执行场所就是模板。Flask-Bootstrap基模板中定义的块:doc, head, title, styles, body, navbar, content, scriptsBootstrap官方文档CDN本地加速:修改 Base.html,引用本地的css 文件,里面元素跟Bootstrap 重名的,则会覆盖官方里相同元素html v

16、iew plain copy1.% block head % 2. super() 3. 4. 5. link rel=stylesheet href=/ 6. link rel=stylesheet href=/ 7.% endblock % 8.。 9.% block scripts % 10. super() 11. script src=/ 12. script src=/ 13. moment.include_moment() 14. moment.lang(zh-CN) 15.% endblock % 自定义错误页面python view plain copy1.app.error

17、handler(404) 2.def page_not_found(e): 3. return render_template(404.html), 404 url_for() 链接辅助函数使用url_for()生成动态地址时,将动态部分作为关键字参数传入。例如,url_for(user, name=john, _external=True)的返回结果是http:/localhost:5000/user/john使用Flask-Moment本地化日期和时间。查阅文档html view plain copy1.%block scripts % 2. super() 3. moment.inclu

18、de_moment() 4. 5. moment.lang(zh-CN) 6.%endblock % 4 Web Form表单app.config字典可用来存储框架、扩展和程序本身的配置变量。使用标准的字典句法就能把配置值添加到app.config对象中。这个对象还提供了一些方法,可以从文件或环境中导入配置值。Form基类由Flask-WTF扩展定义,所以从flask.ext.wtf中导入。字段和验证函数 可以直接从WTForms包中导入。python view plain copy1.from flask_wtf import Form 2.from wtforms import Strin

19、gField, SubmitField 3.from wtforms.validators import DataRequired 4.class NameForm(Form): 5. name = StringField(What is your name?, validators=DataRequired() 6. submit = SubmitField(Submit) WTForms支持的HTML标准字段:StringField,TextAreaField,PasswordField。WTForms内建的验证函数:Email,DataRequired.Placeholder提示:pyt

20、hon view plain copy1.password = PasswordField(Password, validators=DataRequired(), render_kw=placeholder: u密码) 重定向和用户会话刷新页面后会再次提交表单。大多数情况下,这并不是理想的处理方式。很多用户都不理解浏览器发出的这个警告。 基于这个原因,最好别让 Web 程序把 POST 请求作为浏览器发送的最后一个请求。这个技巧称为Post/重定向/Get模式。python view plain copy1.app.route(/, methods=GET, POST) 2.def inde

21、x(): 3. form = NameForm() 4. if form.validate_on_submit(): 5. sessionname = form.name.data 6. return redirect(url_for(index) 7. return render_template(index.html, form=form, name=session.get(name) 使用get()获取字典中键对应的值以避免未找到键的异常情况,因为对于不存在的键,get()会返回默认值None。Flash消息仅调用flash()函数并不能把消息显示出来,程序使用的模板要渲染这些消息。最好

22、在base.html 中渲染Flash消息,因为这样所有页面都能使用这些消息。Flask把get_flashed_messages()函数开放给模板,用来获取并渲染消息5 数据库2016-6-9使用SQL还是NoSQLSQL 数据库擅于用高效且紧凑的形式存储结构化数据。这种数据库需要花费大量精力保证数据的一致性。NoSQL 数据库放宽了对这种一致性的要求,从而获得性能上的优势。MySQL Q&A:安装MySQL in Windows 报错:需要预先把Windows Defender 打开,或者configure mysql server时,不要勾选“Windows Firewall”可能要先安

23、装:Microsoft Visual C+ Compiler for Python 2.7本地安装MySQLdb: pip install mysql-pythonWindow7 64位下安装可能还会报 cl.exe错workaround: 先conda install mysql-python,再手动复制以下目录及文件到 venvLibSite-packages下:Anaconda2Libsite-packagesMySQLdbAnaconda2Libsite-packagesMySQL_python-1.2.5.dist-infoAnaconda2Libsite-packages_mysq

24、l*MySQL创建connection之后,还需要创建“schema” - 对应SQLAlchemy里的“database”MySQLdb 中文乱码的处理:conn = MySQLdb.connect(host=localhost, user=root, passwd=XXX, db=app_englishgo, charset = utf8)显示:title.encode(gbk)接收输入:unicode(request.formtitle)SQLAlchemy 和MongoEngine:数据库抽象层代码包(ORM、ODM),你可以使用这些抽象包直接处理高等级的 Python 对象,而不用处

25、理如表、文档或查询语言此类的数据库实体。使用Flask-SQLAlchemy管理数据库MySQL mysql:/username:passwordhostname:port/databaseSQLite(Windows) sqlite:/c:/absolute/path/to/databaseRelationship 关系型数据库python view plain copy1.class Role(db.Model): 2.# . 3. users = db.relationship(User, backref=role) # 面向对象视角 4.class User(db.Model): 5.

26、# . 6. role_id = db.Column(db.Integer, db.ForeignKey(roles.id) # 定义外键 SQLAlchemy 完整的命令、过滤器、查询执行 列表参见 SQLAlchemy 文档SQLAlchemy engine设置编码,防止中文乱码:python view plain copy1.engine = create_engine(sqlite:/C:Temptestsqlalchemy.db, encoding=utf8, convert_unicode=True, echo=True) 2.# echo:显示出内部过程及SQL语句。debug或

27、学习时打开 3.# encoding:防止乱码 python view plain copy1.mysql:/uid:pwdlocalhost/mydb?charset=utf8 集成Python shell每次启动 shell 会话都要导入数据库实例和模型。为避免重复导入,我们可以做些配置,让 Flask-Script 的 shell 命令自动导入特定的对象。为 shell 命令注册一个 make_context 回调函数新数据库迁移 flask-migrate由于模型中经常会新加一行或几行column (比如用来保存账户的确认状态),此时要修改 models.py,并执行一次新数据库迁移M

28、ySQL Workbench 自动产生EER,可以清楚地看到各个表格之间关系:一对多 Foreign_Key、Index等1) config.py: python view plain copy1.class DevelopmentConfig(Config): 2. DEBUG = True 3. # SQLALCHEMY_DATABASE_URI = os.environ.get(DEV_DATABASE_URL) or sqlite:/ + os.path.join(basedir, data-dev.sqlite) 4. SQLALCHEMY_DATABASE_URI = mysql:

29、/USER:PASSWORDlocalhost:3306/flaskr 2) python manage.py deploy3) MySQL Workbench: Database - Reverse Engineer - 选择 connection - database - 一路 Next6 E-mail使用Flask-Mail提供电子邮件支持python view plain copy1.app.configMAIL_SERVER = 2.app.configMAIL_PORT = 25 3.app.configMAIL_USE_TLS = True 4.app.configMAIL_US

30、ERNAME = os.environ.get(MAIL_USERNAME) 5.app.configMAIL_PASSWORD = os.environ.get(MAIL_PASSWORD) 6.app.configFLASKY_MAIL_SUBJECT_PREFIX = Flasky 7.app.configFLASKY_MAIL_SENDER = Flasky Admin 8.app.configFLASKY_ADMIN = os.environ.get(FLASKY_ADMIN) 9. 10.mail = Mail(app) 11. 12.def sendmail(mail): 13.

31、 msg = Message(test subject, sender=ezhqing, recipients = XXX) 14. msg.body = text body 15. msg.html = HTML body 16. with app.app_context(): 17. mail.send(msg) 千万不要把账户密令直接写入脚本,特别是当你计划开源自己的作品时。让脚本从本机环境中导入敏感信息Windows 用户可按照下面的方式设定环境变量:plain view plain copy1.(venv) $ set MAIL_USERNAME= 2.(venv) $ set MA

32、IL_PASSWORD= 所有的在cmd命令行下对环境变量的修改只对当前窗口有效,不是永久性的修改。也就是说当关闭此cmd命令行窗口后,将不再起作用。永久性修改环境变量的方法有两种:一种是直接修改注册表(overkill python script),另一种是通过我的电脑-属性-高级,来设置系统的环境变量异步发送电子邮件为了避免处理请求过程中不必要的延迟,我们可以把发送电子邮件的函数移到后台线程(Threading)中很多 Flask 扩展都假设已经存在激活的程序上下文和请求上下文。Flask-Mail 中的 send() 函数使用 current_app ,因此必须激活程序上下文。不过,在不

33、同线程中执行 mail.send() 函数时,程序上下文要使用 app.app_context() 人工创建。7 大型程序的结构项目结构plain view plain copy1.|-flasky 2. |-app/ Flask 程序一般都保存在名为 app 的程序包中 3. |-templates/ templates 和 static 文件夹是程序包的一部分 4. |-static/ 5. |-main/ 程序包中创建了一个子包,用于保存蓝本。/main/_init_.py脚本的末尾导入views.py & errors.py,避免循环导入依赖 6. |-_init_.py 程序工厂函数

34、 create_app(),注册蓝本 7. |-errors.py 错误处理路由. 注册程序全局的错误处理程序,必须使用 app_errorhandler 8. |-forms.py 表单对象 9. |-views.py 路由。蓝本中的全部端点会加上一个命名空间,如 url_for(main.index) 10. |-_init_.py 11. |-email.py 电子邮件支持函数 12. |-models.py 数据库模型 13. |-migrations/ 数据库迁移脚本 14. |-tests/ 单元测试 15. |-_init_.py 文件可以为空,因为 unittest 包会扫描所

35、有模块并查找测试 16. |-test*.py 17. |-venv/ 虚拟环境 18. |-requirements.txt 列出了所有依赖包,便于在其他电脑中重新生成相同的虚拟环境 19. |-config.py 存储配置。开发、测试和生产环境要使用不同的数据库 20. |-manage.py 用于启动程序以及其他的程序任务 requirements.txt 文件,用于记录所有依赖包及其精确的版本号。以便要在另一台电脑上重新生成虚拟环境创建:(venv) $ pip freeze requirements.txt恢复:(venv) $ pip install -r requirements

36、.txt 重组后的程序和单脚本版本使用不同的数据库,可使用如下命令创建数据表或者升级到最新修订版本:(venv) $ python manage.py db upgrade8 用户认证Flask的认证扩展Flask-Login:管理已登录用户的用户会话。 Werkzeug:计算密码散列值并进行核对。 itsdangerous:生成并核对加密安全令牌。 创建认证蓝本对于不同的程序功能,我们要使用不同的蓝本(main, auth),这是保持代码整齐有序的好方法因为 Flask 认为模板的路径是相对于程序模板文件夹而言的。为避免与 main 蓝本和后续添加的蓝本发生模板命名冲突,可以把蓝本使用的模板

37、保存在单独的文件夹中使用Flask-Login认证用户LoginManager 对象的 session_protection 属性可以设为 None 、 basic 或 strong ,以提供不同的安全等级防止用户会话遭篡改。设为 strong 时,Flask-Login 会记录客户端 IP地址和浏览器的用户代理信息,如果发现异动就登出用户。为了保护路由只让认证用户访问,Flask-Login 提供了一个 login_required 修饰器current_user 由 Flask-Login 定义,且在视图函数和模板中自动可用模板中加入用户登录后的信息和提示效果 base.html:1. 2

38、. % if current_user.is_authenticated % 3. Log Out current_user.username 4. % else % 5. Log In 6. % endif % 7. 按照第 4 章介绍的“Post/ 重定向 /Get 模式”,Login的 POST 请求最后也做了重定向,不过目标 URL 有两种可能。用户访问未授权的 URL 时会显示登录表单,Flask-Login 会把原地址保存在查询字符串的next参数中,这个参数可从 request.args 字典中读取。如果查询字符串中没有 next 参数,则重定向到首页app/auth/views

39、.pypython view plain copy1.user = User.query.filter_by(email=form.email.data).first() 2.if user is not None and user.verify_password(form.password.data): 3. login_user(user, form.remember_me.data) 4. return redirect(request.args.get(next) or url_for(main.index) 用户注册表单 app/auth/forms.py这个表单使用 WTForms

40、 提供的 Regexp 验证函数,确保 username 字段只包含字母、数字、下划线和点号。密码要输入两次。此时要验证两个密码字段中的值是否一致,这种验证可使用WTForms 提供的另一验证函数实现,即 EqualTo如果表单类中定义了以validate_ 开头且后面跟着字段名的方法,这个方法就和常规的验证函数一起调用发送确认邮件使用itsdangerous生成确认令牌python view plain copy1. from itsdangerous import TimedJSONWebSignatureSerializer as Serializer 2. s = Serializer(app.configSECRET_KEY, expires_in = 3600) 3. token = s.dumps( confirm: 23 ) 4. token 5.eyJhbGciOiJIUzI1NiIsImV4cCI6MTM4MTcxODU1OC

展开阅读全文
相似文档                                   自信AI助手自信AI助手
猜你喜欢                                   自信AI导航自信AI导航
搜索标签

当前位置:首页 > 教育专区 > 其他

移动网页_全站_页脚广告1

关于我们      便捷服务       自信AI       AI导航        获赠5币

©2010-2024 宁波自信网络信息技术有限公司  版权所有

客服电话:4008-655-100  投诉/维权电话:4009-655-100

gongan.png浙公网安备33021202000488号   

icp.png浙ICP备2021020529号-1  |  浙B2-20240490  

关注我们 :gzh.png    weibo.png    LOFTER.png 

客服