flask-day9:flask_migrate|wtforms表单

用flask_migrate管理model,映射数据库

flask_script用脚本运行项目命令

目的是为了在远程访问环境下使项目脱离Pycharm等IDE运行,而能直接通过python manager.py db update形式的命令行命令进行操作数据库。方法是将flask_sqlalchemy完成的代码分解成app.py(模型),config.py(DB_URI等配置内容),db_script.py(要执行的函数),manager.py(入口文件)

config.py(包含了SQLALCHEMY访问数据库和其他参数配置)

# ---coding:utf-8----
# 文件名: config.py
# @Time:2020/4/27 15:20
MYSQL = 'mysql'
PYMYSQL = 'pymysql'
HOST = '120.24.*.*'
PORT = '3306'
DATABASE = 'school'
USERNAME = 'python'
PASSWORD = '*'
DB_URI = '{mysql}+{pymysql}://{username}:{password}@{host}:{port}/{database}?charset=utf8'.format(mysql=MYSQL,pymysql=PYMYSQL,username=USERNAME, password=PASSWORD,host=HOST, port=PORT,database=DATABASE)

SQLALCHEMY_DATABASE_URI = DB_URI
SQLALCHEMY_TRACK_MOFIFICATIONS = False

app.py(模型)

rom flask import Flask
from flask_sqlalchemy import SQLAlchemy
import config
app = Flask(__name__)
# 从config.py中读取SQLALCHEMY配置
app.config.from_object(config)
db = SQLAlchemy(app)

class BackendUser(db.Model):
    __tablename__ = 'backend_user'
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    username = db.Column(db.String(50), nullable=False)
    email = db.Column(db.String(50),nullable=False)
    def __repr__(self):
        return self.username

#db_script.py(flask_script脚本)

from flask_script import Manager
db_manager = Manager()

@db_manager.command    #使用命令装饰符,可以运行命令
def init():
    print("初始化迁移目录")

@db_manager.command
def revision():
    print("生成迁移脚本")

@db_manager.command
def upgrade():
    print("脚本映射到数据库成功")

manager.py(入口文件)

from flask_script import Manager
from app import app
from db_script import db_manager

manager = Manager(app)   #1.flask_script的Manager实例化,注册app
manager.add_command('db',db_manager) #2.增加命令:命令名称


if __name__ == "__main__":
    manager.run()

可以在命令窗口运行:python manager.py db init会运行自定义的init函数,出现"初始化迁移目录"

  • 如果直接在manager.py中增加命令,可以使用python manager.py greet来运行:
@manager.command
def greet():
    print("hello,nihao!")

运行:python manager.py greet,会出现"hello,nihao!"

  • 可以增加参数,实现增加数据 如python manager.py add_user -u zhangsan -e abc@sdf.com
@manager.option("-u","--username",dest="username")   #使用装饰器传参(将参数通过命令行传给项目)
@manager.option("-e","--email",dest="email")    #第二个参数 
def add_user(username,email):
    user = BackendUser(username=username,email=email)
    db.session.add(user)
    db.session.commit()

运行:python manager.py add_user -u zhangsan -e zhangsan@sa.com,会在数据库中增加记录

flask_migrate

在实际的开发环境中,经常会发生数据库修改的行为。一般我们修改数据库不会直接手动的去修改,而是去修改ORM对应的模型,然后再把模型映射到数据库中。这时候如果有一个工具能专门做这种事情,就显得非常有用了,而flask-migrate就是做这个事情的。flask-migrate是基于Alembic进行的一个封装,并集成到Flask中,而所有的迁移操作其实都是Alembic做的,他能跟踪模型的变化,并将变化映射到数据库中。

  1. config.py 配置
DB_HOST = '120.24.*'
DB_PORT = '3306'
DB_NAME = 'school'
DB_USERNAME = 'python'
DB_PASSWORD = '*'
DB_URI = 'mysql+pymysql://{username}:{password}@{host}:{port}/{db}?charset=utf8mb4'.format(username=DB_USERNAME,password=DB_PASSWORD,host=DB_HOST,port=DB_PORT,db=DB_NAME)

SQLALCHEMY_DATABASE_URI = DB_URI
SQLALCHEMY_TRACK_MODIFICATIONS = False
  1. exts.py 扩展用于创建db实例,用于models.py建表,用于app.py
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()              #db来自flask_sqlalchemy,用于操作数据库
  1. models.py 建表的模型,用db建表
from exts import db
class ClassMate(db.Model):
    __tablename__ = 'classmate'
    id = db.Column(db.Integer,primary_key=True,autoincrement=True)
    username = db.Column(db.String(50),nullable=False)
    age = db.Column(db.Integer)
  1. app.py
from flask import Flask
import config
from exts import db

app = Flask(__name__)
app.config.from_object(config) #读取配置
db.init_app(app)  #db绑定app

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

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

  1. manager.py flask_migrate在本文件管理ORM
# ---coding:utf-8----
# 文件名: manager.py
# @Time:2020/4/27 18:59
from flask_migrate import Migrate, MigrateCommand
from flask_script import Manager
from models import ClassMate   #要导入此类,否则不能生成classmates表
from app import app
from exts import db

manager = Manager(app)   #创建了一个manager对象,以支持自定义命令的配置
Migrate(app,db)   #创建一个Migrate对象并关联对应的应用程序类对象app和数据库管理类对象db

manager.add_command('db',MigrateCommand)  #将MigrateCommand命令加入到manager对象中,这样就可以在命令行中进行数据库迁移的相关命令

if __name__ == "__main__":
    manager.run()

完成后,用命令行进行创建一个待迁移的仓库

python test.py db init
=== 'db’是在manager.add_command(‘db’,MigrateComand)这句中我们声明的命令行对象名称,init是Migrate命令,表示初始化迁移仓库,运行完成之后,会在当前目录下创建一个migrations的文件夹,用于进行迁移的数据库脚本都放在这里.===

添加好之后,使用下面的命令自动添加迁移的脚本:

python test.py db migrate -m “inition migrate”

使用upgrade和downgrade命令分别向数据库更新数据和从数据库更新数据,使用upgrade命令将本次的改动更新到数据库中:

python test.py db upgrade

验证:查看数据库是否新生成一个classmates的表

需要修改模型(增删改)时,应该在init之后完成,修改模型后使用命令:

python test.py db migrate -m “inition migrate”

确定无误再进行upgrade. (未测试成功)

WTForms

这个库一般有两个作用。第一个就是做表单验证,把用户提交上来的数据进行验证是否合法。第二个就是做模版渲染。

  1. pip install wtforms
  2. forms.py (由wtforms进行表单元素的渲染与验证,不需要在模板html上定义表单元素和验证了)
# ---coding:utf-8----
# 文件名: forms.py
# @Time:2020/4/28 20:01
from wtforms import Form, StringField, SubmitField
from wtforms.validators import Length, EqualTo
# 通过定义一个类来定义表单元素,这个类继承自wtforms的Form类
class RegisterForm(Form):  
    username = StringField(validators=[Length(min=3,max=10,message="长度3-10")])   #生成一个文本框,名为username,用validators规定验证规则
    password1 = StringField(validators=[Length(min=6,max=10,message="长度6-10")])
    password2 = StringField(validators=[EqualTo("password1")])  #与password1完全相同
    submit1 = SubmitField('提交')  #提交按钮
  1. app.py
from flask import Flask, render_template, request
from forms import RegisterForm
app = Flask(__name__)

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

@app.route('/register/',methods=['GET','POST'])
def register():
    form = RegisterForm(request.form)  #用wtforms定义的类生成实例对象form,该对象包含了提交请求内的form部分内容
    if request.method == "GET":
        return render_template("register.html",form=form)  #响应请求,将form发送给页面
    else:
        if form.validate():
            print(form.username.data) #本地打印form中username.data
            print(form.password1.data)
            return 'Successful!'
        else:
            print(form.errors)
            return 'fail'


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

  1. register.html 无需再用等表单元素,由wtforms提供的form进行渲染
<form action="" method="post">
    用户名:{{form.username()}}<br/>
    密码1:{{ form.password1() }}<br/>
    密码2:{{ form.password2() }}<br/>
    {{form.submit1()}}
</form>

  1. manage.py 入口文件
from flask_script import Manager
from app import app
manager = Manager(app)
if __name__ == "__main__":
    manager.run()

运行:

python manage.py runserver -d -r

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值