浅学flask

浅学flask

Jexi Jiang Lv3

debug模式

如果你的 PyCharm 是中文版,那么你可以参考以下步骤操作

  • 在 PyCharm 的主菜单中,点击 运行 | 编辑配置 。
  • 在 运行/调试配置 对话框中,选择 Flask Server 类型的配置 。
  • 在 Flask Server 配置对话框中,勾选 FLASK_DEBUG 复选框 。这样,每次你保存代码更改时,PyCharm 就会自动重启运行中的应用。

–>路由快速上手_Flask中文网

好处

  • 不需要手动重启服务器
  • 如果出现bug,可以在浏览器中直接调试
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 从flask包中导入flask类
from flask import Flask

# 定义类的对象 app。
# __name__表示当前在app.py这个模块;作用是如果出现bug可以快速定位;以及如果寻找一个模板文件,有一个相对路径。
app = Flask(__name__)

# 创建一个路由,('/')表示根路由
@app.route('/')
def hello_world(): # put application's code here
return 'rtyl'

# 表示如果这个模块当作主入口文件运行,就运行一下代码。
if __name__ == '__main__':
app.run()

修改host

  • 作用:让同一个局域网内其他电脑访问我的项目
  • 怎么做
    • 选择运行|调试配置(在绿色运行符号的左边)
    • 点击编辑配置
    • 在其他选项中写:--host=0.0.0.0
    • 选择ok

修改端口号

如果5000端口被占用,就需要修改到其他端口

怎么做

  • 选择运行|调试配置(在绿色运行符号的左边)
  • 点击编辑配置
  • 在其他选项中写:--host=0.0.0.0后加一个”空格“写入 --port=8000
    • --host=0.0.0.0 --port=8000
    • 让端口号由5000变为8000

url与视图的映射

  • 三种方式
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
from flask import Flask, request

app = Flask(__name__)


@app.route('/')
def hello_world(): # put application's code here
return 'Hello World!'

# 1.定义无参数url
@app.route('/index')
def index():
return '你好中国'

# 2.带参数的url:将参数固定到path中
# <参数>:参数放尖括号里面
# % blog_id是一个占位符,表示将blog_id的值插入到字符串中。
@app.route("/blog/passage <int:blog_id>")
def blog_detail(blog_id):
return "您访问的博客是:%s" % blog_id

# 3.查寻url的方式传参
# args:arguments(参数)
# request.args类字典类型
# f表示寻找{变量}
# book/passage?page=2
@app.route('/book/passage')
def passage_page():
page = request.args.get('page', default=1, type=int)
return f"获取的是第{page}的图书页数"

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

模板渲染(跳过)

  • 引入 from flask import Flask, render_template,

    • rander_template
  • from flask import Flask, render_template
    
    app = Flask(__name__)
    
    
    @app.route('/')
    def hello_world():  
        return render_template("index.html") #这个html是在template里的,这个函数起到渲染这个html文件的作用
    
    
    if __name__ == '__main__':
        app.run()
    
    
    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

    # Flask连接SQL数据库

    ## Navicat Premium 15

    + 它是数据库的管理工具,包括**MySQL**、MariaDB、MongoDB、Oracle、PostgreSQL和SQLite等。
    + 支持可视化操控数据库

    ### MySQL

    > MySQL 是一种用于管理数据库的工具

    #### 数据库

    + pymysql是Python编程语言下的一个用于连接MySQL的数据库

    ## SQLALchemy

    * SQLAlchemy是Python编程语言下的一款ORM框架

    * ORM是Object-Relational Mapping的缩写,即对象关系映射。

    # ORM模型与表的映射

    * 一个orm模型和数据库中的一个表相对应
    * orm技术提供了面向对象和sql交互的桥梁
    * ```python
    class User(db.Model):
    __tablename__ = "user"
    id = db.Column(db.Integer, primary_key = True, autoincrement = True)
    username = db.Column(db.String(100), nullable= False)
    password = db.Column(db.String(100), nullable=False)

ORM模型的CRUD操作

  • 增加(Create)
1
2
3
4
5
6
7
8
9
@app.route("/user/add")
def add_user():
# 1.创建ORM对象
user = User(username="张三",password="123456")
# 2.将ORM对象添加到db.session中
db.session.add(user)
# 3.将db.session中的改变同步到数据库中
db.session.commit()
return "用户创建成功!"
  • 读取(Read)
1
2
3
4
5
@app.route("/user/query")
def query_user():
user = User.query.get(1)
print(f"{user.id}:{user.username}-{user.password}")
return "数据查询成功!"
  • 更新(Update)
1
2
3
4
5
6
@app.route("/user/update")
def update_user():
user = User.query.get(1)
user.password = "2222222"
db.session.commit()
return "数据修改成功!"
  • 删除(Delete)
1
2
3
4
5
6
7
@app.route("/user/delete")
def delete_user():
user = User.query.get(1)
db.session.delete(user)
db.session.commit()
return "数据删除成功!"

ORM模型外键与表的关系

  • 在Mysql中,外键可以让表之间关系变得更加紧密, 在SQlAlchemy 中, 通过ForeignKey类来实现,并且可以指定表的外键约束

author_id = db.Column(db.Integer, db.ForeignKey("user.id"))

  • author = db.relationship("User", backref="articles")表示将User表和articles表互相关联(只要写一个就可以互相关联)
  • author = db.relationship("User", back_populates= "articles")
    
    atticles = db.relationship("User", back_populates= "author")
    
    # 两行代码对应两个位置都要写,这样才可以互相关联
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11

    # flask-migrate 迁移ORM模型

    * 安装``flask-migrate`
    * `from flask-migrate import Migrate`写在开头
    * 在终端三部曲

    * ```terminal
    flask db init # 只要写一次
    flask db migrate # 之后如果修改了表格,只要输入后两项
    flask db upgrade

jinja2

渲染模板

  • @app.route("/blog/<blog_id>")
    def blog_detail(blog_id):
        return render_template("blog_detail.html", blog_id = blog_id, username = "你好")
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    * `{{name}}`表示传入了一个动态参数,在return函数的时候传入相应的参数就可
    * 在template里面就放html文件,文件名字就是blog_detail.html

    ## 模板返回对象属性

    * 对于传入的参数中有多个属性的情况下,可以用 `.`来选你要显示的属性
    *

    # 实战

    ## 问答平台项目实战搭建

    ### 项目架构

    1. #### 创建 `config`.py文件

    1. 比如一些配置内容要写在里面
    2. 与app.py进行绑定

    1. ```python
    import config
    app.comfig.from_object(config)#绑定配置信息
  1. 创建 exts.py文件(拓展文件)

    1. 作用

      1. 这个文件存在的意义是为了解决循环引用的问题
    2. 在exts中写:

      1. from flask_sqalalchemy import SQLAlchemy
        
        db = SQLAlchemy()
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        3. ![flask.1](/images/浅学flask/flask.1.png)
        4. 创建了db对象,现在进行和app绑定

        1. 在app中写

        1. ```python
        from exts import db

        db.init_app(app)
        实行了先创建,再绑定再作用
  2. 创建 models.py文件

  3. 创建 blueprints python包(蓝图)

    1. 作用:

      1. 将视图函数模块化,分类方便后期管理
      2. 比如可以放一个授权区和一个问答区,就可以这样写:
        1. auth.py
        2. qa.py
    2. 在auth中可以写

      1. from flask import Blueprint
        
        bp = Blueprint("auth", __name__, url_prefix="/auth")# 名字,固定写法,url前缀
        
        @bp.route("/login")
        def login():
            ddfjssdfodfp.
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        3. 在qa中可以这样写

        1. ```python
        from flask import Blueprint

        bp = Blueprint("qa", __name__, url_prefix="/") # 只写一个斜杆,表示根路径

        @bp.route("/")
        def index:
        pass
    3. 与app进行绑定

      1. from blueprints.qa import bp as qa_bp
        from blueprints.auth import bp as auth_bp #取个别名,避免重复
        
        app.register_blueprint(qa_bp)
        app.register_blueprint(auth_bp)# 注册蓝图
        
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16

        ## User模型创建

        * 在models文件中

        ```python
        from exts import db
        from datetime import datetime


        class UserModel(db.Model):
        __tablename__ = "user"
        id = db.Column(db.Integer, primary_key=True, autoincrement=True)
        username = db.Column(db.String(100), nullable=False)
        password = db.Column(db.String(100), nullable=False, unique=True)
        join_time = db.Column(db.DateTime, default=datetime.now)
  • 在app文件中

    1
    2
    3
    4
    5
    6
    from models import UserModel #导入UserModel
    from flask_migrate import Migrate #迁徙ORM模型


    migrate = Migrate(app, db) #赋值

注册模板渲染

  • 需求:前端提供静态页码代码,后端要把它渲染成动态页面

    • 方法1:用jinja
      • 视图函数写在auth蓝图里
      • 渲染模板要导入 render_template
      • 静态模板里的相对路径改成用url_for的方式,这样就可匹配动态页面找到对应的样式匹配成功
        • flask.2
        • 修改后flask.3
  • 对于相同的内容,可以把相同的内容提取出来,之后写入到base.html中,然后在原文件中只要用

    • {% block 内容名 %}{% endblock %}
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
        * 这样就可以实现对于特殊内容的替换

      ## flask发送邮箱功能实现

      1. 安装模块 `pip install flask-mail`
      2. 在qq邮箱中开启smtp
      3. 在 `config`文件中

      ```python
      # 邮箱配置
      MAIL_SERVER = "smtp.qq.com" #如果是选网易邮箱,就把qq换掉
      MAIL_USE_SSL = "True"
      MAIL_USERNAME = 465
      MAIL_PASSWORD = "开启SMTP服务时生成的授权码"
      MAIL_DEFAULT_SENDER = "邮箱账号"
    1. exts文件中

      1
      2
      3
      from flask_mail import Mail

      mail = Mail()
    2. app文件中

      基本逻辑就是:导入+初始化 —> 之后就可以用了

      1
      2
      3
      from exts inport mail

      mail.init_app(app)
    3. 测试一下:在 auth文件中

      1
      2
      3
      4
      5
      6
      7
      from exts import mail

      @bp.route("/mail/test")
      def mail_test():
      message = Message(subject = "邮箱设置", recipients = [你的接收邮箱, body = "这是一条测试邮箱" ])
      mail.sent(message)
      return "邮件发送成功!

发送邮箱验证码功能实现

  1. auth文件中

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    from flask import request
    import string
    import random

    @bp.route("/capture/email")
    def get_email_capture():
    email = request.args.get("email")# args,就是传输的意思
    source = string.digits*4 #从这个包中选随机的数字
    capture = random.sample(source, 4)
    # print(capture),发现是列表,要变成字符串
    capture = "-".join(capture) # 把每个字符串连接起来,中间是"-"
    message = Message(subject = "验证码", recipients = [你的接收邮], body = "这是一条测试邮箱" )
    mail.sent(message)
    return "success"
    1. 验证用户提交的邮箱和验证码是否对应正确

      1. 存储一下,可以放在memcached/redis(因为不是很重要的信息),这两个还是要学的。

      2. 或者用数据库存储

        1. 缺点,读取比较慢

        2. 写法:

          1. models文件中

            1
            2
            3
            4
            5
            6
            class EmailCaptureModel(db.Model):
            __tablename__ = "email_capture"
            id = db.Column(db.Integer, primary_key=True, autoincrement=True)
            email = db.Column(db.String(100), nullable=False)
            capture = db.Column(db.String(100), nullable=False)

          2. auth文件中

            1
            2
            3
            4
            5
            6
            7
            from models import EmailCaptureModel, db

            # 写在mail下的shi'tu
            email_capture = EmailCaptureModel(email = email, capture = capture)
            db.session.add(email_capture)
            db.session.commit()
            return "success!"
  • Title: 浅学flask
  • Author: Jexi Jiang
  • Created at : 2024-01-14 21:27:31
  • Updated at : 2024-01-16 09:33:35
  • Link: https://milefer7.github.io/Jaxi-Jiang-Blog/2024/01/14/浅学flask/
  • License: This work is licensed under CC BY-NC-SA 4.0.
Comments