flask框架学习

flask框架学习

pycharm创建项目,连接到远程gitee仓库,创建仓库flask_study,分支helloworld,

自带第一个程序"helloworld",运行程序,访问127.0.0.1/即可显示helloworld

1、配置相关

开启debug模式

app.py
# app.py内容
from flask import Flask

app = Flask(__name__)
# 设置以下内容,让json中中文正常显示
app.config['JSON_AS_ASCII'] = False


@app.route('/')
def hello_world():
    return {"username": "姓名"}


if __name__ == '__main__':
    app.run()

# 这种方法不方便
config.py
# 方法二:在根目录下设置一个config.py文件并添加以下内容
JSON_AS_ASCII = False
app.py
from flask import Flask
import config

app = Flask(__name__)
app.config.from_object(config)  # 应用配置文件


@app.route('/')
def hello_world():
    return {"username": "姓名"}


if __name__ == '__main__':
    app.run()

2、url和视图映射

app.py
from flask import Flask
import config
import json
app = Flask(__name__)
app.config.from_object(config)

# 通过引用json,使用json.dumps返回请求,效率低,效果差
book_dict = [
    {'id': 1, 'name': "三国", '作者': '施耐庵'},
    {'id': 2, 'name': "西游", '作者': '吴承恩'},
    {'id': 3, 'name': "水浒", '作者': "罗贯中"},
    {'id': 4, 'name': "红楼", '作者': '曹雪芹'},

]


@app.route("/book/list/")
def book_list():
    return json.dumps(book_dict)

@app.route('/')
def hello_world():
    return {"username": "姓名"}


if __name__ == '__main__':
    app.run()

app.py
from flask import Flask,jsonify

book_dict = [
    {'id': 1, 'name': "三国", '作者': '施耐庵'},
    {'id': 2, 'name': "西游", '作者': '吴承恩'},
    {'id': 3, 'name': "水浒", '作者': "罗贯中"},
    {'id': 4, 'name': "红楼", '作者': '曹雪芹'},

]

# 引用flask自带jsonify返回
@app.route("/book/list/")
def book_list():
    return jsonify(book_dict)
app.py
from flask import Flask, jsonify
import config

app = Flask(__name__)
app.config.from_object(config)

book_dict = [
    {'id': 1, 'name': "三国", '作者': '施耐庵'},
    {'id': 2, 'name': "西游", '作者': '吴承恩'},
    {'id': 3, 'name': "水浒", '作者': "罗贯中"},
    {'id': 4, 'name': "红楼", '作者': '曹雪芹'},

]

# 在网址中输入数字,函数获取id值进行搜索
@app.route("/book/<int:book_id>")
def book_detail(book_id):
    for book in book_dict:
        if book_id == book['id']:
            return jsonify(book)
    return "没找到"


@app.route("/book/list/")
def book_list():
    return jsonify(book_dict)


@app.route('/')
def hello_world():
    return {"username": "姓名"}


if __name__ == '__main__':
    app.run()
app.py
from flask import Flask, jsonify, url_for
import config


app = Flask(__name__)
app.config.from_object(config)

book_dict = [
    {'id': 1, 'name': "三国", '作者': '施耐庵'},
    {'id': 2, 'name': "西游", '作者': '吴承恩'},
    {'id': 3, 'name': "水浒", '作者': "罗贯中"},
    {'id': 4, 'name': "红楼", '作者': '曹雪芹'},

]


@app.route("/book/<int:book_id>")
def book_detail(book_id):
    for book in book_dict:
        if book_id == book['id']:
            return jsonify(book)
    return "没找到"


@app.route("/book/list/")
def book_list():
    # 导入url_for,向book_dict中添加对用的url/id
    for book in book_dict:
        book['url'] = url_for("book_detail", book_id=book['id'])
    return jsonify(book_dict)


@app.route('/')
def hello_world():
    return {"username": "姓名"}


if __name__ == '__main__':
    app.run()

3、method请求

1、如果只是需要从服务器获取数据,一般都是用GET请求

2、如果前端需要把数据发送给服务器,一般是POST请求

3、在装饰器里直接加入 methods = ['GET',"POST"],也可以指定某一种请求方式

Request对象的重要属性如下所列:

Form - 它是一个字典对象,包含表单参数及其值的键和值对。
args - 解析查询字符串的内容,它是问号(?)之后的URL的一部分。
Cookies - 保存Cookie名称和值的字典对象。
files - 与上传文件有关的数据。
method - 当前请求方法。
————————————————
版权声明:本文为CSDN博主「爱编程的喵汪人」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_42415326/article/details/90374936

@app.route("/book/<int:book_id>", methods=['POST',"GET"])
def book_detail(book_id):
    for book in book_dict:
        if book_id == book['id']:
            return jsonify(book)
    return "没找到"
# 参数的传递形式
# 1、作为url的组成方式: /book/1
# 2、查询字符串 /book?id=1
app.py

redirect(url_for("hellow_world")) # 重定向-hello_world的函数的网址,

user_id = request.args.get('id') # 使用get方法获得网址里输入的id

from flask import Flask, jsonify, url_for, redirect, request
import config

@app.route("/profile")
def profile():
    # 参数的传递形式
    # 1、作为url的组成方式: /book/1
    # 2、查询字符串 /book?id=1
    user_id = request.args.get('id')
    if user_id:
        return "用户个人中心"
    else:
        return redirect(url_for('hello_world'))

@app.route('/')
def hello_world():
    return {"username": "姓名"}


4、jinjia2模板

模板概述

所有HTML文件存放在templates中

render_template  # 此方法默认从templates中寻找
# 可以更改,一般不更改
app.py

向render_template中传参数,并在about中显示出来

from flask import Flask, render_template

app = Flask(__name__)


@app.route('/about/')
def about():
    # 默认在templates中寻找,一般不更改
    context = {
        'username': 'name',
        'age': 'age',
    }
    return render_template('about.html', **context)


@app.route('/')
def hello_world():
    return 'Hello World!'


if __name__ == '__main__':
    app.run()
about.html
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>关于我们</title>
</head>
<body>
<h1>这只是一个简单的模板文件</h1>
<p>{{ username }}</p>
<p>{{ age }}</p>
</body>
</html>
概述总结:
  1. 模板文件,也就是html文件,需要放到templates文件夹下,当然在Flask(__name__,template_folder)来修改模板的地址,但是不推荐。
  2. 通过render_template来渲染模板。
  3. 如果想要传递变量到模板中,那么可以把变量定义成字典,然后在render_template中,通过关键字参数的方式传递过去。render_template('',**context)

jinjia2模板过滤器

{{ username|length }}

过滤器是通过管道符号(|)进行使用的,例如:{{ name|length }},将返回name的长度。过滤器相当于是一个函数,把当前的变量传入到过滤器中,然后过滤器根据自己的功能,再返回相应的值,之后再将结果渲染到页面中。Jinja2中内置了许多过滤器,在这里可以看到所有的过滤器,现对一些常用的过滤器进行讲解:

常用的过滤器
  1. abs(value):返回一个数值的绝对值。 例如:-1|abs

  2. default(value,default_value,boolean=false):如果当前变量没有值,则会使用参数中的值来代替。name|default('xiaotuo')——如果name不存在,则会使用xiaotuo来替代。boolean=False默认是在只有这个变量为undefined的时候才会使用default中的值,如果想使用python的形式判断是否为false,则可以传递boolean=true。也可以使用or来替换。

  3. escape(value)或e:转义字符,会将<>等符号转义成HTML中的符号。例如:content|escapecontent|e

  4. first(value):返回一个序列的第一个元素。names|first

  5. format(value,*arags,**kwargs):格式化字符串。例如以下代码:

    {{ "%s" - "%s"|format('Hello?',"Foo!") }}
    

    将输出:Helloo? - Foo!

  6. last(value):返回一个序列的最后一个元素。示例:names|last

  7. length(value):返回一个序列或者字典的长度。示例:names|length

  8. join(value,d=u''):将一个序列用d这个参数的值拼接成字符串。

  9. safe(value):如果开启了全局转义,那么safe过滤器会将变量关掉转义。示例:content_html|safe

  10. int(value):将值转换为int类型。

  11. float(value):将值转换为float类型。

  12. lower(value):将字符串转换为小写。

  13. upper(value):将字符串转换为小写。

  14. replace(value,old,new): 替换将old替换为new的字符串。

  15. truncate(value,length=255,killwords=False):截取length长度的字符串。

  16. striptags(value):删除字符串中所有的HTML标签,如果出现多个空格,将替换成一个空格。

  17. trim:截取字符串前面和后面的空白字符。

  18. string(value):将变量转换成字符串。

  19. wordcount(s):计算一个长字符串中单词的个数。

控制语句

所有的控制语句都是放在{% ... %}中,并且有一个语句{% endxxx %}来进行结束,Jinja中常用的控制语句有if/for..in..,现对他们进行讲解:

  1. if:if语句和python中的类似,可以使用>,<,<=,>=,==,!=来进行判断,也可以通过and,or,not,()来进行逻辑合并操作,以下看例子:

    {% if kenny.sick %}
    	Kenny is sick.
    {% elif kenny.dead %}
    	You killed Kenny!  You bastard!!!
    {% else %}
    	Kenny looks okay --- so far
    {% endif %}
    
  2. for...in...for循环可以遍历任何一个序列包括列表、字典、元组。并且可以进行反向遍历,以下将用几个例子进行解释:

    • 普通的遍历:

      <ul>
      {% for user in users %}
      <li>{{ user.username|e }}</li>
      {% endfor %}
      </ul>
      
    • 遍历字典:

      <dl>
      {% for key, value in my_dict.iteritems() %}
      	<dt>{{ key|e }}</dt>
      	<dd>{{ value|e }}</dd>
      {% endfor %}
      </dl>
      
    • 如果序列中没有值的时候,进入else

      <ul>
      {% for user in users %}
      	<li>{{ user.username|e }}</li>
      {% else %}
      	<li><em>no users found</em></li>
      {% endfor %}
      </ul>
      

并且Jinja中的for循环还包含以下变量,可以用来获取当前的遍历状态:

变量 描述
loop.index 当前迭代的索引(从1开始)
loop.index0 当前迭代的索引(从0开始)
loop.first 是否是第一次迭代,返回True或False
loop.last 是否是最后一次迭代,返回True或False
loop.length 序列的长度

另外,不可以使用continuebreak表达式来控制循环的执行。

模板继承

不同于django,flask中继承时,引入css文件的方法是,使用url_for

{% block head %}
<link href="{{ url_for('static', filename = 'css/index.css') }}" rel="stylesheet">
{% endblock %}

5、视图高级

蓝图

在项目根目录创建一个python包,apps

在apps中,创建三个py文件分别为,book.py course.py user.py

book.py
from flask import Blueprint

# url_prefix设置网络地址前缀 1270.0.0.1:5000/book
bp = Blueprint('book', __name__, url_prefix='/book/')


@bp.route('/list/')
def book_list():
    return '图书列表'
course.py
from flask import Blueprint

# url_prefix设置网络地址前缀 1270.0.0.1:5000/book
bp = Blueprint('course', __name__, url_prefix='/course/')


@bp.route('/list/')
def course_list():
    return '课程列表'
user.py
from flask import Blueprint

# url_prefix设置网络地址前缀 1270.0.0.1:5000/book
bp = Blueprint('user', __name__, url_prefix='/user/')


@bp.route('/list/')
def user_list():
    return '用户列表'

在app.py中导入三个文件

使用函数register_blueprint拼接

from flask import Flask
from apps import book, course, user

app = Flask(__name__)

# 注册蓝图
app.register_blueprint(book.bp)
app.register_blueprint(user.bp)
app.register_blueprint(course.bp)


@app.route('/')
def hello_world():
    return 'Hello World!'


if __name__ == '__main__':
    app.run(debug=True)
说明:

在apps中的每一个py文件,如果要重定向到某个html文件,写法和app.py一样,默认还是文件夹templates和static

6、数据库插件sqlalchemy

Flask-SQLAlchemy笔记

一、SQLAlchemy和Flask-SQLAlchemy的区别:

  1. SQLAlchemy:是一个独立的ORM框架,可以独立于Flask存在,也可以在其他项目中使用,比如在Django中。
  2. Flask-SQLAlchemy:对SQLAlchemy的一个封装,能够更适合在flask中使用。

一、安装和验证:

  1. 安装连接数据库的库:pip install pymysql
  2. 安装:pip install flask-sqlalchemy

二、连接数据库:

# 数据库的配置变量
HOSTNAME = '127.0.0.1'
PORT     = '3306'
DATABASE = 'xt_flask'
USERNAME = 'root'
PASSWORD = 'root'
DB_URI = 'mysql+pymysql://{}:{}@{}:{}/{}'.format(USERNAME,PASSWORD,HOSTNAME,PORT,DATABASE)

app.config['SQLALCHEMY_DATABASE_URI'] = DB_URI
app.py
from flask import Flask
import pymysql
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

# 数据库的配置变量
HOSTNAME = '127.0.0.1'
PORT = '3306'
DATABASE = 'staff_info'
USERNAME = 'root'
PASSWORD = 'wocaonima'
DB_URI = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(USERNAME, PASSWORD, HOSTNAME, PORT, DATABASE)
app.config['SQLALCHEMY_DATABASE_URI'] = DB_URI
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app)


@app.route('/')
def hello_world():
    # 写个测试代码验证是否研究成功

    engine = db.get_engine()
    # conn = engine.connect()
    # conn.close()
    with engine.connect() as conn:
        result = conn.execute('select 1;')
        print(result.fetchone())
    return 'Hello World!'


if __name__ == '__main__':
    app.run(debug=True)

三、创建模型:

app.py
数据库操作:
from flask import Flask
import pymysql
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

# 数据库的配置变量
HOSTNAME = '127.0.0.1'
PORT = '3306'
DATABASE = 'flask_test'
USERNAME = 'root'
PASSWORD = 'wocaonima'
DB_URI = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(USERNAME, PASSWORD, HOSTNAME, PORT, DATABASE)
app.config['SQLALCHEMY_DATABASE_URI'] = DB_URI
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app)


# 定义ORM模型
class Article(db.Model):
    __tablename__ = 'article'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    title = db.Column(db.String(200), nullable=False)
    content = db.Column(db.Text, nullable=False)


db.create_all()


@app.route('/')
def hello_world():
    # 写个测试代码验证是否研究成功

    engine = db.get_engine()
    # conn = engine.connect()
    # conn.close()
    with engine.connect() as conn:
        result = conn.execute('select 1;')
        print(result.fetchone())
    return 'Hello World!'


@app.route('/article')
def article_view():
    # 1、添加数据
    article = Article()
    article.title = '骆驼祥子'
    article.content = '虎妞'

    db.session.add(article)
    # 提交
    db.session.commit()
    return '成功'


@app.route('/article/1')
def article_query():
    # 1、查询数据
    article = Article().query.filter_by(id=1)[0]
    print(article.title)

    return article.title


@app.route('/article/upgrade')
def article_upgrade():
    # 1、查询数据,返回一个类对象
    article = Article().query.filter_by(id=1)[0]

    article.title = '骆驼老顾'
    db.session.commit()
    return article.title

@app.route('/article/delete')
def article_delete():
    # 1、删除,返回一个类对象
    article = Article().query.filter_by(id=1).delete()

    db.session.commit()
    return "article.title"


if __name__ == '__main__':
    app.run(debug=True)
设置外键
author_id = db.Column(db.Integer, db.ForeignKey("user.id"))  # 设置外键
数据库迁移

pip install flask-migrate #先安装第三方模块

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate

app = Flask(__name__)

# 数据库的配置变量
HOSTNAME = '127.0.0.1'
PORT = '3306'
DATABASE = 'flask_test'
USERNAME = 'root'
PASSWORD = 'wocaonima'
DB_URI = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(USERNAME, PASSWORD, HOSTNAME, PORT, DATABASE)
app.config['SQLALCHEMY_DATABASE_URI'] = DB_URI
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app)


# 迁移数据库
migrate = Migrate(app, db)

终端输入 :

flask db init

flask db migrate -m "first commit"

flask db upgrade

第二次迁移,例如向user加一个password字段

flask db migrate -m "add password to user"

flask db upgrade

第三次迁移,例如从user删除password字段

flask db migrate -m "remove password from user"

flask db upgrade

四、表关系:

1. 一对多 app.py:

创建表时,设置一个外键和relationship

from flask import Flask
import pymysql
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

# 数据库的配置变量
HOSTNAME = '127.0.0.1'
PORT = '3306'
DATABASE = 'flask_test'
USERNAME = 'root'
PASSWORD = 'wocaonima'
DB_URI = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(USERNAME, PASSWORD, HOSTNAME, PORT, DATABASE)
app.config['SQLALCHEMY_DATABASE_URI'] = DB_URI
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app)


# 定义ORM模型
class User(db.Model):
    __tablename__ = 'user'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    username = db.Column(db.String(200), nullable=False)


# 定义ORM模型
class Article(db.Model):
    __tablename__ = 'article'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    title = db.Column(db.String(200), nullable=False)
    content = db.Column(db.Text, nullable=False)
    author_id = db.Column(db.Integer, db.ForeignKey("user.id"))  # 设置外键

    # 通过外键绑定关系,第一个参数和另一个表的名字一样, backref代表反向引用,即被访问时的字段名称, relationship的前提是必须已经有外键
    author = db.relationship("User", backref='articles')


# 不迁移就得先删除所有表然后再创建
db.drop_all()
db.create_all()


@app.route("/one2many/")
def one2many():
    article1 = Article(title='刚忒1', content='xxx')
    article2 = Article(title='刚忒2', content='xxx')
    user = User(username="强子")
    article1.author = user
    article2.author = user
    db.session.add(article1, article2)  # 添加一个两个都添加进去了
    db.session.commit()
    print(user.articles)
    return 'success'


if __name__ == '__main__':
    app.run(debug=True)

2. 一对一 app.py:
from flask import Flask
import pymysql
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)

# 数据库的配置变量
HOSTNAME = '127.0.0.1'
PORT = '3306'
DATABASE = 'flask_test'
USERNAME = 'root'
PASSWORD = 'wocaonima'
DB_URI = 'mysql+pymysql://{}:{}@{}:{}/{}?charset=utf8'.format(USERNAME, PASSWORD, HOSTNAME, PORT, DATABASE)
app.config['SQLALCHEMY_DATABASE_URI'] = DB_URI
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app)


# 定义ORM模型
class User(db.Model):
    __tablename__ = 'user'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    username = db.Column(db.String(200), nullable=False)


class UserExtension(db.Model):
    __tablename__ = 'user_extension'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    school = db.Column(db.String(100))
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
    # 反向引发是,uselist=false,禁止使用列表,即达成一对一
    user = db.relationship("User", backref=db.backref('extension', uselist=False))


# 定义ORM模型
class Article(db.Model):
    __tablename__ = 'article'

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    title = db.Column(db.String(200), nullable=False)
    content = db.Column(db.Text, nullable=False)
    author_id = db.Column(db.Integer, db.ForeignKey("user.id"))  # 设置外键

    # 通过外键绑定关系,第一个参数和另一个表的名字一样, backref代表反向引用,即被访问时的字段名称, relationship的前提是必须已经有外键
    author = db.relationship("User", backref='articles')


# 不迁移就得先删除所有表然后再创建
db.drop_all()
db.create_all()


@app.route("/o2o/")
def o2o():
    user = User(username='学霸')
    extension = UserExtension(school="北大")
    user.extension = extension
    db.session.add(user)
    db.session.commit()
    return 'das'


@app.route("/one2many/")
def one2many():
    article1 = Article(title='刚忒1', content='xxx')
    article2 = Article(title='刚忒2', content='xxx')
    user = User(username="强子")
    article1.author = user
    article2.author = user
    db.session.add(article1, article2)  # 添加一个两个都添加进去了
    db.session.commit()
    print(user.articles)
    return 'success'




if __name__ == '__main__':
    app.run(debug=True)
3. 多对多:

7、代码重构

创建一个单独的

app.config.from_object(config)  # 导入配置文件

迁移的时候,容易引起db的循环,解决方法为:将db放在一个单独的py文件exts,先不要绑定db,待app.py读取到配置好文件,再进行数据库和app的绑定,如下:

# 把app绑定到dbdb.init_app(app)

8、cookie和session

cookie和session

  1. cookie:在网站中,http请求是无状态的。也就是说即使第一次和服务器连接后并且登录成功后,第二次请求服务器依然不能知道当前请求是哪个用户。cookie的出现就是为了解决这个问题,第一次登录后服务器返回一些数据(cookie)给浏览器,然后浏览器保存在本地,当该用户发送第二次请求的时候,就会自动的把上次请求存储的cookie数据自动的携带给服务器,服务器通过浏览器携带的数据就能判断当前用户是哪个了。cookie存储的数据量有限,不同的浏览器有不同的存储大小,但一般不超过4KB。因此使用cookie只能存储一些小量的数据。
  2. session: session和cookie的作用有点类似,都是为了存储用户相关的信息。不同的是,cookie是存储在本地浏览器,session是一个思路、一个概念、一个服务器存储授权信息的解决方案,不同的服务器,不同的框架,不同的语言有不同的实现。虽然实现不一样,但是他们的目的都是服务器为了方便存储数据的。session的出现,是为了解决cookie存储数据不安全的问题的。
  3. cookiesession结合使用:web开发发展至今,cookiesession的使用已经出现了一些非常成熟的方案。在如今的市场或者企业里,一般有两种存储方式:
    • 存储在服务端:通过cookie存储一个session_id,然后具体的数据则是保存在session中。如果用户已经登录,则服务器会在cookie中保存一个session_id,下次再次请求的时候,会把该session_id携带上来,服务器根据session_idsession库中获取用户的session数据。就能知道该用户到底是谁,以及之前保存的一些状态信息。这种专业术语叫做server side session。存储在服务器的数据会更加的安全,不容易被窃取。但存储在服务器也有一定的弊端,就是会占用服务器的资源,但现在服务器已经发展至今,一些session信息还是绰绰有余的。
    • session数据加密,然后存储在cookie中。这种专业术语叫做client side sessionflask采用的就是这种方式,但是也可以替换成其他形式。

flask中使用cookie和session

  1. cookies:在

    Flask
    

    中操作

    cookie
    

    ,是通过

    response
    

    对象来操作,可以在

    response
    

    返回之前,通过

    response.set_cookie
    

    来设置,这个方法有以下几个参数需要注意:

    • key:设置的cookie的key。
    • value:key对应的value。
    • max_age:改cookie的过期时间,如果不设置,则浏览器关闭后就会自动过期。
    • expires:过期时间,应该是一个datetime类型。
    • domain:该cookie在哪个域名中有效。一般设置子域名,比如cms.example.com
    • path:该cookie在哪个路径下有效。
  2. session:Flask中的session是通过from flask import session。然后添加值key和value进去即可。并且,Flask中的session机制是将session信息加密,然后存储在cookie中。专业术语叫做client side session

app.py
from flask import Flask, Response, request, session

app = Flask(__name__)
app.config["SECRET_KEY"] = '123'


@app.route('/set_cookie/')
def set_cookie():
    response = Response("cookie 设置")
    response.set_cookie("user_id", 'xxx')
    return response


@app.route("/set_session")
def set_session():
    session['username'] = 'name'
    return 'set_session'


@app.route("/get_session")
def get_session():
    username = session.get('username')
    print(username)
    return 'sadas'


@app.route('/get_cookie/')
def get_cookie():
    user_id = request.cookies.get("user_id")
    print(user_id)
    return '获取cookie'


@app.route('/')
def hello_world():
    return 'Hello World!'


if __name__ == '__main__':
    app.run()

9、Flask-WTF表单验证

Flask-WTF是简化了WTForms操作的一个第三方库。WTForms表单的两个主要功能是验证用户提交数据的合法性以及渲染模板。当然还包括一些其他的功能:CSRF保护,文件上传等。安装Flask-WTF默认也会安装WTForms,因此使用以下命令来安装Flask-WTF:

pip install flask-wtf

一、表单验证:

安装完Flask-WTF后。来看下第一个功能,就是用表单来做数据验证,现在有一个forms.py文件,然后在里面创建一个RegistForm的注册验证表单:

class RegistForm(Form):
    name = StringField(validators=[length(min=4,max=25)])
    email = StringField(validators=[email()])
    password = StringField(validators=[DataRequired(),length(min=6,max=10),EqualTo('confirm')])
    confirm = StringField()

在这个里面指定了需要上传的参数,并且指定了验证器,比如name的长度应该在4-25之间。email必须要满足邮箱的格式。password长度必须在6-10之间,并且应该和confirm相等才能通过验证。

写完表单后,接下来就是regist.html文件:

<form action="/regist/" method="POST">
    <table>
        <tr>
            <td>用户名:</td>
            <td><input type="text" name="name"></td>
        </tr>
        <tr>
            <td>邮箱:</td>
            <td><input type="email" name="email"></td>
        </tr>
        <tr>
            <td>密码:</td>
            <td><input type="password" name="password"></td>
        </tr>
        <tr>
            <td>确认密码:</td>
            <td><input type="password" name="confirm"></td>
        </tr>
        <tr>
            <td></td>
            <td><input type="submit" value="提交"></td>
        </tr>
    </table>
</form>

再来看视图函数regist

@app.route('/regist/',methods=['POST','GET'])
def regist():
    form = RegistForm(request.form)
    if request.method == 'POST' and form.validate():
        user = User(name=form.name.data,email=form.email.data,password=form.password.data)
        db.session.add(user)
        db.session.commit()
        return u'注册成功!'
    return render_template('regist.html')

RegistForm传递的是request.form进去进行初始化,并且判断form.validate会返回用户提交的数据是否满足表单的验证。

二、渲染模板:

form还可以渲染模板,让你少写了一丢丢的代码,比如重写以上例子,RegistForm表单代码如下:

class RegistForm(Form):
    name = StringField(u'用户名:',validators=[length(min=4,max=25)])
    email = StringField(u'邮箱:'validators=[email()])
    password = StringField(u'密码:',validators=[DataRequired(),length(min=6,max=10),EqualTo('confirm')])
    confirm = StringField(u'确认密码:')

以上增加了第一个位置参数,用来在html文件中,做标签提示作用。

app中的视图函数中,修改为如下:

@app.route('/regist/',methods=['POST','GET'])
def regist():
    form = RegistForm(request.form)
    if request.method == 'POST' and form.validate():
        user = User(name=form.name.data,email=form.email.data,password=form.password.data)
        db.session.add(user)
        db.session.commit()
        return u'注册成功!'
    return render_template('regist.html',form=form)

以上唯一的不同是在渲染模板的时候传入了form表单参数进去,这样在模板中就可以使用表单form变量了。

接下来看下regist.html文件:

<form action="/regist/" method="POST">
    <table>
        <tr>
            <td>{{ form.name.label }}</td>
            <td>{{ form.name() }}</td>
        </tr>
        <tr>
            <td>{{ form.email.label }}</td>
            <td>{{ form.email() }}</td>
        </tr>
        <tr>
            <td>{{ form.password.label }}</td>
            <td>{{ form.password() }}</td>
        </tr>
        <tr>
            <td>{{ form.confirm.label }}</td>
            <td>{{ form.confirm() }}</td>
        </tr>
        <tr>
            <td></td>
            <td><input type="submit" value="提交"></td>
        </tr>
    </table>
</form>

7、文件上传

用 Flask 处理文件上传非常简单。需要在HTML表单form中,确保设置其enctype属性为“multipart / form-data”,就可以将文件发布到URL,URL处理程序从request.files[]对象中提取文件,并将其保存到所需的位置。

posted @   还是啥都不会  阅读(316)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· .NET10 - 预览版1新功能体验(一)
点击右上角即可分享
微信分享提示