flask-migrate,flask-script

Flask-Migrate是一个为Flask应用处理SQLAlchemy数据库迁移的扩展,使得可以通过Flask的命令行接口或者Flask-Scripts对数据库进行操作。
Flask-Script:用来生成shell命令;为在Flask里编写额外的脚本提供了支持。
这包括运行一个开发服务器,一个定制的Python命令行,用于执行初始化数据库、定时任务和其他属于web应用之外的命令行任务的脚本。

# 创建迁移仓库(migrations目录)
python script.py  db init
# 读取类的内容, 生成版本文件,  并没有真正在数据库中添加或删除;
python  script.py  db migrate -m "添加性别"
# 在数据库中曾删改;
python script.py  db upgrade
# 检测是否成功?
mysql -uroot -phello
# 去查看改变的历史状态;
python script.py  db history
# 返回指定的版本状态;
python script.py  db downgrade  base

Flask-Script:用来生成shell命令;为在Flask里编写额外的脚本提供了支持。
这包括运行一个开发服务器,一个定制的Python命令行,用于执行
初始化数据库、定时任务和其他属于web应用之外的命令行任务的脚本。

添加自定义命令的3中方式:
- 定义Command的子类;
- 使用command装饰器
- 使用option装饰器

from flask import Flask
from flask_script import Manager, Command

app = Flask(__name__)
# 1. 先实例化对象, Manager类实例化的对象运行/启动后, 辉跟踪所有的命令和命令调用的参数;
manager = Manager(app)
# 定义Command的子类;
class Hello(Command):
    """欢迎信息"""
    def run(self):
        print("hello world")

#  添加到命令中, 让马哪个而进行管理
manager.add_command('hello', Hello)

# 使用command装饰器
@manager.command
def add_user():
    """添加用户"""
    print("添加用户成功!")
# 使用option装饰器 入符哦命令需要添加参数时
# -n 简写, --name, 全称,
@manager.option('-n', '--name', help="删除用户的名称")
@manager.option('-p', '--passwd', help="删除用户的密码")
def delete_user(name, passwd):
    """删除用户"""
    if name:
        print("删除用户%s成功, 密码为%s!" %(name, passwd))
    else:
        print("用户为空")
# 使用option装饰器
if __name__ == "__main__":
    manager.run()

Todo
manage

from flask_migrate import  Migrate, MigrateCommand
from flask_script import  Shell, Manager
from models import app, db, User, Department
# 用来管理命令的对象, Manager用来跟踪所有名林不过并处理他们如何从命令行调用;
manager = Manager(app)
migrate = Migrate(app, db)
# 添加一条数据库迁移管理的命令
manager.add_command('db', MigrateCommand)

#  添加一条命令, 可以显示所有的用户
@manager.command
def showUser():
    """显示所有的用户"""
    users = User.query.all()
    print(users[:5])

#  添加一条命令, 可以显示所有的用户
@manager.command
def showDepart():
    """显示所有的部门"""
    deaprts  = Department.query.all()
    print(deaprts)

 # 添加部门
@manager.option('-n', '--name', help="部门名称")
def add_depart(name):
    try:
        depart1 = Department(name=name)
        db.session.add(depart1)
        db.session.commit()
    except Exception:
        print("创建部门失败!")
    else:
        print("创建部门%s成功!" %(name))
#  实现添加用户的命令
if __name__ == "__main__":
    # 准备
    manager.run()

models

from datetime import datetime
from flask import Flask
from flask_sqlalchemy import  SQLAlchemy
from flask_bootstrap import  Bootstrap

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql+pymysql://root:hello@localhost/Todo'
# SQLAlchemy 将会追踪对象的修改并且发送信号。
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
db = SQLAlchemy(app)
bootstrap = Bootstrap(app)
app.config['SECRET_KEY'] = 'hello'
#  1). 面向对象方式创建表
#  2). 分析关系:
#       部门和用户: 一对多
#       用户和任务: 一对多的关系
#       用户和用户登录日志: 一对多的关系
#  实现一对多(Role(1): User(n))的关系
#   - 多的一端写外键
#   - 少的一端写反向引用

class User(db.Model):
    id = db.Column(db.Integer, autoincrement=True, primary_key=True)
    # unique:用户名唯一, nullable=False指用户名不能为空;
    name = db.Column(db.String(50), unique=True, nullable=False)
    pwd = db.Column(db.String(100))
    email = db.Column(db.String(30), unique=True)
    phone = db.Column(db.String(30), unique=True)
    info = db.Column(db.Text)  # 个人简介
    add_time = db.Column(db.DateTime, default=datetime.now())   # 创建时间
    department_id = db.Column(db.Integer, db.ForeignKey('department.id'))
    todos = db.relationship('Todo', backref='user')
    userlogs = db.relationship('Userlog', backref='user')
    # 部门id与其他表关联,不能随便写

    def __repr__(self):
        return  '' %(self.name)


# 部门
class Department(db.Model):
    id = db.Column(db.Integer, autoincrement=True, primary_key=True)
    name = db.Column(db.String(50), unique=True, nullable=False)
    #  反向引用: user就包含一个属性, department
    users = db.relationship('User', backref='department')
    todos = db.relationship('Todo', backref='department')

    def __repr__(self):
        return  '' %(self.name)

class Todo(db.Model):
    id = db.Column(db.Integer, autoincrement=True, primary_key=True)
    name = db.Column(db.String(200), nullable=False)
    add_time = db.Column(db.DateTime, default=datetime.now())  # 创建时间
    status = db.Column(db.Boolean, default=False)  # 任务状态, 默认为Flase(未完成)
    department_id = db.Column(db.Integer, db.ForeignKey('department.id'))
    user_id = db.Column(db.Integer,db.ForeignKey('user.id') )

    def __repr__(self):
        return '' % (self.id)

# 用户登录日志
class Userlog(db.Model):
    id = db.Column(db.Integer, autoincrement=True, primary_key=True)
    add_time = db.Column(db.DateTime, default=datetime.now())  # 创建时间
    ip = db.Column(db.String(200), nullable=False) # 登录ip
    area =  db.Column(db.String(200))  # 用户登录地点
    user_id = db.Column(db.Integer, db.ForeignKey('user.id'))  # 外键


    def __repr__(self):
        return '' % (self.ip)



if __name__ == '__main__':
    db.create_all()

    # # 2). 初始化数据
    # parts = ['开发部', '运维部', '人事部']
    # partObj = [Department(name=part) for part in parts]
    # db.session.add_all(partObj)
    # db.session.commit()

    u1 = User(name="user1", pwd='redhat', department_id=1)
    db.session.add(u1)
    db.session.commit()

views

from flask import render_template, request, redirect, url_for

from models import app, Todo, db, Department


@app.route('/')
def index():
    return render_template('base.html')
@app.route('/register/')
def register():
    pass
@app.route('/login/')
def login():
    pass
@app.route('/logout/')
def logout():
    pass

# 任务的增删改查
@app.route('/todo/add/', methods=['POST'])
def todo_add():
    # 获取提交的任务信息
    name = request.form['todo_name']
    part = request.form['part']
    # 添加完成之后, 返回任务列表显示页面
    todo = Todo(name=name, department_id=part, user_id=1)
    db.session.add(todo)
    db.session.commit()

    return  redirect(url_for('todo_list'))


@app.route('/todo/delete/')
def todo_delete(id):
    pass


@app.route('/list/')
def todo_list():
    # 1). 从数据库中查询
    todos = Todo.query.all()
    parts = Department.query.all()

    return  render_template('list.html',
                            todos = todos,
                            parts=parts)

# 修改任务的状态(变成已完成状态/变成未完成状态)
@app.route('/todo/undo//')
def undo(id):
    todo = Todo.query.filter_by(id=id).first()
    todo.status = False
    db.session.commit()
    # 更新状态后, 返回任务列表页
    return redirect(url_for('todo_list'))

@app.route('/todo/done//')
def done(id):
    todo = Todo.query.filter_by(id=id).first()
    todo.status = True
    db.session.commit()
    # 更新状态后, 返回任务列表页
    return redirect(url_for('todo_list'))

run

# 项目真实运行脚本
from  models import  app
# 导入编写的视图函数和路由
from views import  *
if __name__ == '__main__':
    app.run()

base.html

{#自己编写一个基类模板#}
{% extends "bootstrap/base.html" %}

{% block styles %}
    {{ super() }}
    
{% endblock %}


{% block navbar %}
    
{% endblock %}



{% block content %}
    {#定义属于自己的block#}
    {% block  newcontent %}

    {% endblock %}

    {% block footer %}

        

    {% endblock %}
{% endblock %}

list.html

{% extends 'base.html' %}

{% block newcontent %}
    
{# 添加框 #}
{# 选择框 #}
{# 添加的按钮 #}

添加任务

{% for todo in todos %} {# #} {% endfor %}
任务内容 创建时间 状态 所属部门 操作
{{ todo.name }} {{ todo.add_time }} {% if todo.status %} 已完成 {% else %} 未完成 {% endif %} {{ todo.department.name }}
{% endblock %}

你可能感兴趣的:(flask-migrate,flask-script)