Flask orm

2023-09-10  本文已影响0人  biubiudog

Flask部分:

app.py文件:

from flask import Flask

app = Flask(__name__)

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

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

SQLAlchemy部分:

pip install flask_sqlalchemy

2 初始化SQLAlchemy对象

from flask_sqlalchemy import SQLAlchemy

HOSTNAME = '127.0.0.1'
PORT = 3306
USERNAME = 'root'
PASSWORD = 'root'
# mysql创建的数据库名称
DATABASE = 'xxxx'

SQLALCHEMY_DATABASE_URI = f"mysql+pymysql://{USERNAME}:{PASSWORD}@{HOSTNAME}:{PORT}/{DATABASE}?charset=utf8mb4"
app.config['SQLALCHEMY_DATABASE_URI'] = SQLALCHEMY_DATABASE_URI
db = SQLAlchemy(app)

Migrate部分

pip install flask-migrate

2.初始化migrate对象

from flask-migrate import Migrate
migrate = Migrate(app, db)
  1. ORM映射生成三步:
 - flask db init  只需要执行一次
 - flask db migrate 识别orm对象的改变,生成迁移脚本
 - flask db upgrade  运行迁移脚本,同步到数据库中

config配置

app.py中

import config
app.config.from_object(config)
#替换在app.py中config配置如:app.config['SQLALCHEMY_DATABASE_URI'] = ''

解决循环导入问题:

生成exts.py

#解决循环导入的问题
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()

app.py中修改:

from exts import db
from models import User

db.init_app(app)

models.py中

from exts import db

flask-mail使用

使用时,需要个人邮箱或者企业邮箱设置中找到POP3/SMTP服务点击开启,会有一个授权码。

pip install flask-mail
#exts文件中写入:
from flask-mail import Mail
mail = Mail()
#app.py中引入:
from exts import mail
mail.init_app(app)
#邮箱服务器配置
#config文件中写入
MAIL_SERVER = "smtp.qq.com"
MAIL_USE_SSL = True
MAIL_PORT = 465
MAIL_USERNAME = "邮箱账号"
MAIL_PASSWORD = "开启SMTP服务时生成的授权码"
MAIL_DEFAULT_SENDER = "邮箱账号"
from flask_mail import Message
# sender:邮件的发件人地址。默认值为 None,需要在 Flask 应用程序配置中定。
# recipients:邮件的收件人地址,可以是字符串类型或列表类型。
# subject:邮件的主题,字符串类型。
# body:邮件的正文内容,字符串类型。
# cc:邮件的抄送地址,可以是字符串类型或列表类型。
# bcc:邮件的秘密抄送地址,可以是字符串类型或列表类型。
# html:邮件的 HTML 格式内容,字符串类型。
# charset:邮件的编码格式,默认为 utf-8。
# attachments:邮件的附件列表,每个附件是一个元组,包含附件名和附件内容。

message = Message(subject="邮箱测试", recipients="xxx@qq.com", body="这是一条测试邮件")
mail.send(message)

邮箱验证码


ORM模型使用

user = User(username="xx", .....)
db.session.add(user)
db.session.commit

表单验证

flask-wtf

pip install flask-wtf
pip install email_validator #邮箱验证需要

使用

import wtforms
from wtforms.validators import Email, EqualTo, Length
from models import User

class RegisterForm(wtforms.Form):
    email = wtforms.StringField(validators=[Email("邮箱格式错误")])
    captcha = wtforms.StringField(validators=[Length(min=6, max=6, message="验证码格式错误")])
    username = wtforms.StringField(validators=[Length(min=4, max=20, message="用户名格式错误")])
    password = wtforms.StringField(validators=[Length(min=4, max=20, message="密码格式错误")])
    confirm = wtforms.StringField(validators=[EqualTo("password", message="两次密码不一致")])

    #自定义判断:
    # 验证用户名是否唯一
    def validate_username(self, field):
        # 想要获取其他信息:使用self.xxx,如self.email
        username = field.data
        user = User.query.filter_by(username=username).first()
        if user:
            raise wtforms.ValidationError(message="用户名已存在")

app.py中调用:


image.png

用户的密码加密:

from werkzeug.security import generate_password_hash, check_password_hash

#加密存库:
user = User(username=username, password=generate_password_hash(password), email=email)

#判断密码是否一致
generate_password_hash(password), email=email)

#登录实现
@bp.route('/login')
def login():
    if request.method == 'GET':
        return render_template('login.html')
    else:
        form = LoginForm(request.form)
        if form.validate():
            username = form.username.data
            password = form.password.data
            user = User.query.filter_by(username=username).first()
            if user:
                is_pass = check_password_hash(user.password, password)
                # 用户名密码验证成功
                if is_pass:
                    # cookie中不适合放太多数据,适合存储登录授权相关的信息
                    # flask中的session是通过加密后存储在cookie中的
                    # session使用时需要加密,需在config中配置SECRET_KEY='',设置一个长度大概为20位左右的随机字符,
                    session['user_id'] = user.id
                    redirect(url_for('index'))
                #用户名密码验证失败
                else:
                    return redirect(url_for('auth.login'))
            else:
                #用户没有注册
                return redirect(url_for('auth.register'))
        else:
            # 用户名密码验证失败
            print(form.errors)
            return redirect(url_for('auth.login'))

获取session中存储的用户信息

# 在每个请求之前注册一个要运行的函数,每一次请求都会执行一次。
@app.before_request
def my_before_request():
    user_id = session.get("user_id")
    if user_id:
        user = User.query.get(user_id)
        setattr(g, "user", user)
    else:
        setattr(g, "user", None)

#context_processor上下文处理器,返回的字典可以在全部的模板中使用。
@app.context_processor
def my_context_processor():
    return {"user": g.user}

钩子函数

上一篇 下一篇

猜你喜欢

热点阅读