概述

  • Flask采用MVT模型,即Model, Template, View

    • Model:定义数据的存储格式,并且提供了数据库访问的API
    • View:定义那些数据被显示,是业务逻辑处理模块
    • Template:定义数据如何被显示

实例1(简单实例)

  • 在项目文件夹创建虚拟环境,安装依赖包

    • virtualenv venv
    • venv\Scripts\activate
    • pip install –r  requirements.txt
  • 创建程序实例app,是一个Flask类的对象
  • 客户端(浏览器)把请求发送给Web服务器,Web服务器再把请求发送给Flask程序实例,程序实例需要知道对每个URL运行哪些代码,在Flask中通过app.route装饰器定义,保存了一个URL到Python函数的映射关系(路由)
  • 路由后面的函数是视图函数,视图函数的返回值称为响应,是客户端接收到的内容
  • <>中的内容为动态路由,用于生成针对个人的欢迎消息
  • run()启动服务,启动后进入轮询,直到Ctrl+C停止
  • Flask从客户端收到请求时,通过视图函数中的请求对象(上下文)保存客户端发送的HTTP请求,Flask中的上下文分为程序(current_app、g)和请求(request、session)两类

requirements.txt

 1 alembic==1.0.1
2 asn1crypto==0.24.0
3 cffi==1.11.5
4 Click==7.0
5 cryptography==2.3.1
6 Flask==1.0.2
7 Flask-Migrate==2.3.0
8 Flask-Script==2.0.6
9 Flask-SQLAlchemy==2.3.2
10 Flask-WTF==0.14.2
11 idna==2.7
12 ItsDangerous==1.1.0
13 Jinja2==2.10
14 Mako==1.0.7
15 MarkupSafe==1.0
16 Pillow==5.3.0
17 pycparser==2.19
18 PyMySQL==0.9.2
19 python-dateutil==2.7.3
20 python-editor==1.0.3
21 six==1.11.0
22 SQLAlchemy==1.2.12
23 Werkzeug==0.14.1
24 WTForms==2.2.1
  • 在templates目录中创建模板文件

index.html

1 <h1>Hello World!</h1>

user.html

1 <h1>Hello, {{ name }}!</h1>
  • 编写主程序文件

python.py

 1 from flask import Flask, render_template
2
3 app = Flask(__name__)
4
5 @app.route('/')
6 def index():
7 return render_template('index.html')
8
9 @app.route('/user/<name>')
10 def user(name):
11 return render_template('user.html', name=name)
12
13 if __name__ == '__main__':
14 app.run(debug=True)
  • 启动项目

    • python hello.py
  • 浏览器访问  

  

实例2(添加css样式,js动态效果)

hello.py

 1 from flask import Flask, render_template
2
3 app = Flask(__name__)
4
5 @app.route('/')
6 def index():
7 return render_template('index.html')
8
9 @app.route('/user/<name>')
10 def user(name):
11 return render_template('user.html', name=name)
12
13 if __name__ == '__main__':
14 app.run(debug=True)

index.html

 1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>static demo</title>
6 <!-- 使用url_for加载静态文件 url_for第一个参数必须是'static',然后后面跟一个关键字参数filename='文件路径',从static文件夹下面开始寻找的 -->
7 <link rel="stylesheet" href="{{ url_for('static',filename='css/index.css') }}">
8 <script src="../static/js/index.js"></script>
9 </head>
10 <body>
11
12 <p>static demo</p>
13 <div>
14 <img src="{{ url_for('static',filename='images/zhifubao.png') }}" alt="" width="500px" height="500px">
15 </div>
16 </body>
17 </html>

index.css

1 body{
2 background: pink;
3 }

index.js

1 alert('hello world!');

 

实例3(模板渲染,表单,validators)

  • 现在的视图函数中包含两部分:请求改变程序状态,生成请求的响应,这两部分分别称为业务逻辑和表现逻辑,当程序变大时,程序的可维护性会变差。
  • 把表现逻辑移到模板函数中,模板是一个包含响应文本的文件,其中包含用占位符表示的动态部分,具体值需要在请求上下文中得到,替换后再返回最终的响应结果,这一过程称为渲染模板。Flask使用Jinja2作为模板渲染引擎
  • 默认情况下,Flask在程序文件夹中的templates子文件夹中寻找模板,render_template()函数的第一个参数是模板文件名,随后的键值对参数是模板变量中的真实值,左边的变量是参数名,即模板中的占位符,右边的变量是当前作用域中的变量,即同名参数的值
  • 模板中{{ name }}表示变量,是一种特殊的占位符,告诉模板引擎这个位置的值从渲染模板时使用的数据中获取
  • 过滤器:如:Hello, {{ name|capitalize }},以首字母大写形式显示
  • 模板继承:如:{%extends "base.html"%},表示本模板继承自base.html,{% block title %}Index{% endblock %},表示重写的部分
  • 链接:url_for('static', filename='css/styles.css', _external=True),生成:http://localhost:5000/static/css/styles.css
  • request.form获取POST请求中提交的表单数据
  • Flask-WTF能保护所有表单免收跨站请求伪造(Cross-Site Request Forgery,CSRF),为实现CSRF保护,Flask-WTF需要程序设置一个密钥,Flask-WTF使用这个密钥生成加密令牌,再用令牌验证请求中表单数据的真伪
  • app.config字典可用来存储框架、扩展和程序本身的配置变量,SECRET_KEY配置通用密钥,加密强度取决于变量值的机密程度,不同程序要使用不同的密钥,且要确保其他人不知道你所用的字符串,通常将密钥保存在环境变量中,而不直接写入代码
  • 使用Flask-WTF时,每个Web表单都由一个集成自Form的类表示,这个类定义表单中的一组字段,每个字段都用对象表示,字段对象可附属一个或多个验证函数,以验证用户提交的输入值是否符合需求
  • StringField构造函数中的可选参数validators指定一个由验证函数组成的列表,在接受用户提交的数据之前验证数据,验证函数Required()确保提交的字段不为空

index.html

 1 <!DOCTYPE html>
2 <html lang="en">
3 <head>
4 <meta charset="UTF-8">
5 <title>static demo</title>
6 <!-- 使用url_for加载静态文件 url_for第一个参数必须是'static',然后后面跟一个关键字参数filename='文件路径',从static文件夹下面开始寻找的 -->
7 <link rel="stylesheet" href="{{ url_for('static',filename='css/index.css') }}">
8 <script src="../static/js/index.js"></script>
9 </head>
10 <body>
11
12 <div class="page-header">
13 <h1>Hello, {% if name %}{{ name }}{% else %}Stranger{% endif %}!</h1>
14 </div>
15 <form method="POST">
16 {{ form.hidden_tag() }}
17 {{ form.name.label }} {{ form.name() }}
18 {{ form.submit() }}
19 </form>
20 </body>
21 </html>

hello.py

 1 from flask import Flask, render_template
2 from flask_wtf import FlaskForm
3 from wtforms import StringField, SubmitField
4 from wtforms.validators import Required
5
6 app = Flask(__name__)
7 app.config["SECRET_KEY"] = "12345678"
8
9 class NameForm(FlaskForm):
10 name = StringField('What is your name?',
11 render_kw={
12 "type" : "text",
13 "placeholder": "请输入用户名!",
14 "class":"validate-username",
15 "size" : 15})
16 submit = SubmitField('Submit')
17
18 @app.route('/',methods=['GET', 'POST'])
19 def index():
20 name = None
21 form = NameForm()
22 if form.validate_on_submit():
23 name = form.name.data
24 form.name.data = ''
25 return render_template('index.html', form=form, name=name)
26
27 @app.route('/user/<name>')
28 def user(name):
29 return render_template('user.html', name=name)
30
31 if __name__ == '__main__':
32 app.run(debug=True)

实例4(重定向,用户会话,flash消息)

  • 提交用户名后刷新页面,会提示重新提交表单,原因是刷新页面时浏览器会重新发送之前已经发送的最后一个请求,即再次提交表单,为避免这种情况,使用重定向作为POST请求的响应,浏览器收到重定向响应时,会向重定向的URL发起GET请求,显示页面内容,但这样会带来另一个问题,重定向后的页面无法保存之前提交的用户名,解决的办法是使用用户会话(session)保存用户数据,sesseion本质上是一个Python字典,将用户信息保存在用户本地的客户端中
  • 重定向地址使用Flask提供的URL生成函数url_for()生成,参数是端点名,即路由的内部名称,默认情况下就是相应视图函数的名称,即处理根地址的index()。效果和redirect('/')是一样的
  • 请求完成后,需要让用户知道状态发生了变化,可使用flash()函数完成,并在模板中渲染Flash消息

 1 from flask import Flask, render_template, session, redirect, url_for
2 from flask_wtf import FlaskForm
3 from wtforms import StringField, SubmitField
4 from wtforms.validators import Required
5
6 app = Flask(__name__)
7 app.config["SECRET_KEY"] = "12345678"
8
9 class NameForm(FlaskForm):
10 name = StringField('What is your name?',
11 render_kw={
12 "type" : "text",
13 "placeholder": "请输入用户名!",
14 "class":"validate-username",
15 "size" : 15},validators=[Required()])
16 submit = SubmitField('Submit')
17
18 @app.route('/',methods=['GET', 'POST'])
19 def index():
20 form = NameForm()
21 if form.validate_on_submit():
22 session['name'] = form.name.data
23 return redirect(url_for('index'))
24 return render_template('index.html', form=form, name=session.get('name'))
25
26 @app.route('/user/<name>')
27 def user(name):
28 return render_template('user.html', name=name)
29
30 if __name__ == '__main__':
31 app.run(debug=True)

实例5(数据库交互,更改端口)

  • 使用 Flask-SQLAlchemy 管理数据库,完成ORM操作
  • 模型:一个Python类对应一张表,类中属性对应数据库表中的列
  • 数据库操作
    • filter_by():查询
    • add():添加
    • delete():删除
  • 关系(两个类中分别写)
    • users = db.relationship('User', backref='role')
    • role_id = db.Column(db.Integer, db.ForeignKey('roles.id'))
  • 若用户信息在数据库中,则显示欢迎信息,若用户不在数据库中,则在数据库中添加用户
  • 使用 Flask-Migrate 实现数据库迁移,跟踪数据库模式的变化,然后增量式的把变化应用到数据库中
  • 在run()函数中实现服务端口的更改

hello.py

 1 from flask import Flask, render_template, session, redirect, url_for, flash
2 from flask_sqlalchemy import SQLAlchemy
3 from flask_wtf import FlaskForm
4 from wtforms import StringField, SubmitField
5 from wtforms.validators import Required
6 from config import config
7
8 app = Flask(__name__)
9 app.config["SECRET_KEY"] = "12345678"
10 app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:123456@127.0.0.1:3306/shop'
11 app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
12 db = SQLAlchemy(app)
13
14 class NameForm(FlaskForm):
15 name = StringField('What is your name?',
16 render_kw={
17 "type" : "text",
18 "placeholder": "请输入用户名!",
19 "class":"validate-username",
20 "size" : 15},validators=[Required()])
21 submit = SubmitField('Submit')
22
23 @app.route('/',methods=['GET', 'POST'])
24 def index():
25 form = NameForm()
26 if form.validate_on_submit():
27 user = User.query.filter_by(username=form.name.data).first()
28 if user is None:
29 user = User(username = form.name.data)
30 db.session.add(user)
31 session['known'] = False
32 else:
33 session['known'] = True
34 session['name'] = form.name.data
35 form.name.data = ''
36 return redirect(url_for('index'))
37 return render_template('index.html',form = form, name = session.get('name'), known = session.get('known', False))
38
39 class User(db.Model):
40 __tablename__ = 'user'
41 id = db.Column(db.Integer, primary_key=True)
42 username = db.Column(db.String(64))
43 def __repr__(self):
44 return '<User %r>' % self.username
45
46 if __name__ == '__main__':
47 app.run(
48 host = '127.0.0.1',
49 port = 5001,
50 debug=True
51 )

index.html

 1 <!DOCTYPE html>
2 {% extends "base.html" %}
3 {% block page_content %}
4 <html lang="en">
5 <head>
6 <meta charset="UTF-8">
7 <title>static demo</title>
8 <!-- 使用url_for加载静态文件 url_for第一个参数必须是'static',然后后面跟一个关键字参数filename='文件路径',从static文件夹下面开始寻找的 -->
9 <link rel="stylesheet" href="{{ url_for('static',filename='css/index.css') }}">
10 <script src="../static/js/index.js"></script>
11 </head>
12 <body>
13
14 <div class="page-header">
15 <h1>Hello, {% if name %}{{ name }}{% else %}Stranger{% endif %}!</h1>
16 {% if not known %}
17 <p>Pleased to meet you!</p>
18 {% else %}
19 <p>Happy to see you again!</p>
20 {% endif %}
21 </div>
22 <form method="POST">
23 {{ form.hidden_tag() }}
24 {{ form.name.label }} {{ form.name() }}
25 {{ form.submit() }}
26 </form>
27 </body>
28 </html>
29 {% endblock %}

参考

Flask教程

https://yq.aliyun.com/zt/3074776

url_for:静态资源加载

https://www.cnblogs.com/guyuyun/p/9942859.html

https://www.jianshu.com/p/0e77f4eb650c

流程控制

https://blog.csdn.net/xujin0/article/details/96567884

css 样式

https://www.cnblogs.com/yiluhuakai/p/8401740.html

css id class

https://www.runoob.com/css/css-id-class.html

flask jQuery

https://www.cnblogs.com/clnchanpin/p/6920103.html

flask css

https://blog.csdn.net/weixin_33595571/article/details/86608238

{%include%}

https://blog.csdn.net/xujin0/article/details/97102530

前端流程

https://blog.csdn.net/xtaydwxf1988/article/details/75043753

终止服务

https://www.itranslater.com/qa/details/2326227523467740160

表单类

https://blog.csdn.net/kylinxjd/article/details/94645086

https://www.jianshu.com/p/0ba3ec040fb2

CSRF token

https://www.cnblogs.com/mengbin0546/p/9966431.html

登录验证

https://www.jianshu.com/p/06bd93e21945

wtforms注入样式

https://www.cnblogs.com/haiyan123/p/8254228.html

https://greyli.com/flask-form-custom-form-style/

Flask轻量级博客

https://blog.csdn.net/feit2417/article/details/80837297

CentOS部署

https://blog.csdn.net/weixin_43925725/article/details/86742259

GET和POST

https://www.zhihu.com/question/28586791

[Python] Flask从0到1开发轻量级网页的更多相关文章

  1. Python Flask API实现方法-测试开发【提测平台】阶段小结(一)

    微信搜索[大奇测试开],关注这个坚持分享测试开发干货的家伙. 本篇主要是对之前几次分享的阶阶段的总结,温故而知新,况且虽然看起来是一个小模块简单的增删改查操作,但其实涉及的内容点是非常的密集的,是非常 ...

  2. Vue2.0 全家桶开发的网页应用(参照吾记APP)

    github链接 借鉴吾记APP,使用 vue2.0+vue-router+vuex 为主要技术栈,elementui做为ui框架,多模块 spa 模式,webpack2.0 负责模块打包,gulp ...

  3. Python Flask高级编程之从0到1开发《鱼书》精品项目 ☝☝☝

    Python Flask高级编程之从0到1开发<鱼书>精品项目 ☝☝☝ 一 .安装环境我们使用 flask web框架,并用 sqlalchemy来做数据库映射,并使用 migrate做数 ...

  4. Python Flask高级编程之从0到1开发《鱼书》精品项目 ✍✍✍

    Python Flask高级编程之从0到1开发<鱼书>精品项目  一 .安装环境我们使用 flask web框架,并用 sqlalchemy来做数据库映射,并使用 migrate做数据迁移 ...

  5. Python Flask高级编程之从0到1开发《鱼书》精品项目

    Python Flask高级编程之从0到1开发<鱼书>精品项目     整个课程都看完了,这个课程的分享可以往下看,下面有链接,之前做java开发也做了一些年头,也分享下自己看这个视频的感 ...

  6. 实战接口开发:python + flask + mysql + redis(根据反馈,持续细化更新。。。)

    前言 自动化已经成为测试的必备技能之一了,所以,很多想跳槽的测试朋友都在自学,特别是最实用的接口自动化, 但是很多人因为没有可以练手的项目而苦恼,最终导致缺乏实战经验,其实,完全可以自己开发个简单项目 ...

  7. Python 开发轻量级爬虫05

    Python 开发轻量级爬虫 (imooc总结05--网页下载器) 介绍网页下载器 网页下载器是将互联网上url对应的网页下载到本地的工具.因为将网页下载到本地才能进行后续的分析处理,可以说网页下载器 ...

  8. Flask —— 使用Python和OpenShift进行即时Web开发

    最近Packtpub找到了我,让我给他们新出版的关于Flask的书写书评.Flask是一个很流行的Python框架.那本书是Ron DuPlain写的<Flask 即时Web开发>.我决定 ...

  9. Taffy Web开发,Python Flask实践详解

    1. 前言 最近为Taffy自动化测试框架写了个页面,主要实现了用例管理.执行,测试报告查看管理.发送邮件及配置等功能. 2. 实现细节 页面使用Python Flask +Bootstrap开发,还 ...

随机推荐

  1. java例题_29 二维数组问题,并输出对角线之和

    1 /*29 [程序 29 求矩阵对角线之和] 2 题目:求一个 3*3 矩阵对角线元素之和 3 程序分析:利用双重 for 循环控制输入二维数组,再将 a[i][i]累加后输出. 4 */ 5 6 ...

  2. java面试-对象的创建、内存布局、访问定位

    一.对象的创建 1.虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用代表的类是否已被加载.解析和初始化过.如果没有,那必须先执行相应的 ...

  3. MyBatis笔记(六)

    1. 动态SQL 1.1 介绍 概念:**动态SQL指的是根据不同的查询条件 , 生成不同的Sql语句.* 官网描述: MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其 ...

  4. 201871030102_崔红梅 实验三 结对项目—《D{0-1}KP 实例数据集算法实验平台》项目报告

    项目 内容 课程班级博客链接 班级博客 这个作业要求链接 作业要求 我的课程学习目标 1.体验软件项目开发中的两人合作,练习结对编程2. 掌握Github协作开发程序的操作方法.3.阅读<现代软 ...

  5. EFCore3.1+编写自定义的EF.Functions扩展方法

    前言 本文主要是讲解EF Core3.0+ 如何实现自定义的数据库扩展函数 虽然EF.Functions 提供了很多数据库函数,但是并不全面.比如加密解密.. 这样的话 我们就需要自己扩展这些数据库函 ...

  6. JVM(三)类加载与字节码技术

    1.类文件结构 首先获得.class字节码文件 方法: 在文本文档里写入java代码(文件名与类名一致),将文件类型改为.java 在文件对应目录下运行cmd,执行javac XXX.java 以下是 ...

  7. SHA256sum系列命令检测文件完整性

    1 sha256sum sha256sum是一个检测文件完整性的命令,一般下载的文件都会附带一个哈希值,使用sha256sum计算下载文件的哈希值再与目标哈希值比较即可确定文件是否完整,类似的命令还有 ...

  8. Hadoop完整搭建过程(一):本地模式

    1 本地模式 本地模式是最简单的模式,所有模块都运行在一个JVM进程中,使用本地文件系统而不是HDFS. 本地模式主要是用于本地开发过程中的运行调试用,下载后的Hadoop不需要设置默认就是本地模式. ...

  9. 关于GWAS的质量控制步骤顺序疑问?不同指导不同文献的建议各不相同。

          事情是这样的,刚开始接触GWAS就一定会接触到数据质量控制这个东西.我们可以看到网络上各种各样的指导,都是分为individual quality control and snp quan ...

  10. Django 入门范例

    1. Django 介绍 2. Django 环境搭建 3. 模型(Model) 4. 站点管理 5. 视图(View) 6. 模板(Template) 1. Django 介绍 MVC 模型 大部分 ...