Python之Flask框架~多表操作~多对多

1.定义

“多对多”是指关系型数据库中的模型对象的多对多的模型关系,它表示一个模型(即表)的多条记录(即行)对应多个另一个模型(即另一个表)的记录。简单来说,一个模型中的多个记录关联另一个模型中的多个记录。比如多个用户对象可以收藏多部电影对象。

以用户对象以及电影对象为例写个代码

from enum import Enum


class GenderEnum(Enum):
    MALE = '男'
    FEMALE = '女'


# 中间表:收藏表
collect = db.Table(
    'collects',
    db.Column('user_id', db.Integer, db.ForeignKey('tb_movie_users.id'), primary_key=True),
    db.Column('movie_id', db.Integer, db.ForeignKey('tb_movie.id'), primary_key=True),
)


# 电影用户模型
class MovieUserModel(db.Model):
    __tablename__ = "tb_movie_users"
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    username = db.Column(db.String(30), unique=True, index=True)
    age = db.Column(db.Integer, default=1)
    gender = db.Column(db.Enum(GenderEnum))


# 电影模型
class MovieModel(db.Model):
    __tablename__ = "tb_movie"
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    movie_name = db.Column(db.String(30), unique=True, index=True)
    # 关联
    movie_users = db.relationship('MovieUserModel', backref='movies', lazy='dynamic', secondary=collect)

特别说明下,这种多对多模型设置的中间表关联外键时候,如果用 __tablename__指定了表名,那就需要用这个表名,而不是使用小写的模型对象名,不然会引起sqlalchemy.exc.NoReferencedTableError错误,比如“sqlalchemy.exc.NoReferencedTableError: Foreign key associated with column 'collects.user_id' could not find table 'movieusermodel' with which to generate a foreign key to target column 'id'”

2.数据迁移

(1)flask db migrate创建迁移文件(60b44f7a29f9_.py)

(flask_env) PS D:\learn\using_the_flask\模型基础> flask db migrate
INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.autogenerate.compare] Detected added table 'tb_movie'
INFO  [alembic.autogenerate.compare] Detected added index 'ix_tb_movie_movie_name' on '['movie_name']'
INFO  [alembic.autogenerate.compare] Detected added table 'tb_movie_users'
INFO  [alembic.autogenerate.compare] Detected added index 'ix_tb_movie_users_username' on '['username']'        
INFO  [alembic.autogenerate.compare] Detected added table 'collects'
Generating D:\learn\using_the_flask\模型基础\migrations\versions\60b44f7a29f9_.py ...  done

(2)flask db upgrade 执行迁移文件中的upgrade升级,创建数据表

(flask_env) PS D:\learn\using_the_flask\模型基础> flask db upgrade
INFO  [alembic.runtime.migration] Context impl SQLiteImpl.
INFO  [alembic.runtime.migration] Will assume non-transactional DDL.
INFO  [alembic.runtime.migration] Running upgrade e7a1718370d7 -> 60b44f7a29f9, empty message

3.数据操作

(1)增

添加用户

@user_bp.route("/addmu")
def add_movie_user():
    # 添加电影用户
    users_list = []
    for i in range(10):
        # 用户名
        m_user = MovieUserModel()
        m_user.username = f'Shirley{i}'
        m_user.gender = GenderEnum.FEMALE
        users_list.append(m_user)

    try:
        # 添加电影用户列表
        db.session.add_all(users_list)
        db.session.commit()
        return "添加电影用户成功!"
    except:
        db.session.rollback()  # 回滚

添加电影

@user_bp.route("/addmv")
def add_movie():
    # 添加电影
    movies_list = []
    for i in range(1, 10):
        # 电影名
        m_name = MovieModel()
        m_name.movie_name = f'速度与激情{i}'
        movies_list.append(m_name)

    try:
        # 添加电影用户列表
        db.session.add_all(movies_list)
        db.session.commit()
        return "添加电影成功!"
    except:
        db.session.rollback()  # 回滚

接下来重点讲下多对多操作的多表交互的添加,这个是主要内容,在这里是多个用户可以收藏多部电影,可以使用关联关系去添加电影,也可以让电影对象有多个收藏用户

@user_bp.route("/cllmv/<int:u_id>-<int:m_id>")
def add_collect(u_id, m_id):
    """
    某用户收藏某电影
    @param u_id: 电影用户编号
    @param m_id: 电影编号
    @return:
    """
    # 某个用户
    user_obj = MovieUserModel.query.filter(MovieUserModel.id == u_id).first()

    # 某个电影
    movie_obj = MovieModel.query.filter(MovieModel.id == m_id).first()

    # 判断用户或电影是否存在
    if not (user_obj and movie_obj):
        return "请检查输入的用户或电影是否存在!"

    # 收藏电影
    user_obj.movies.append(movie_obj)

    try:
        # 提交
        db.session.commit()
        return "用户收藏成功!"
    except:
        db.session.rollback()  # 回滚
        print(traceback.format_exc())
        return "用户收藏失败!"

(2)删

删除所有电影用户

@user_bp.route("/deluall")
def del_user_all():
    try:

        u_query = MovieUserModel.query.all()
        for u_obj in list(u_query):
            db.session.delete(u_obj)
        db.session.commit()
        return "删除全部用户成功!"
    except:
        db.session.rollback()  # 回滚

(3)改

@user_bp.route("/updmv")
def update_movie():
    # 将前两部电影的名称改为《机械师1》,《机械师2》
    try:
        for i in range(1, 3):
            m = MovieModel.query.get(i)
            m.movie_name = f'机械师{i}'
            db.session.commit()
        return "更新电影信息成功!"
    except:
        db.session.rollback()  # 回滚
        print(traceback.format_exc())
        return "更新电影信息失败!"

(4)查

@user_bp.route("/getmv")
def get_collect():
    # 查询id为8的用户收藏的电影
    user8_movie_info = MovieUserModel.query.get(8).movies
    try:
        return f"id为8的用户收藏了{','.join([mv_obj.movie_name for mv_obj in user8_movie_info])}!"
    except:
        db.session.rollback()  # 回滚
        print(traceback.format_exc())
        return f"查询id为8的用户收藏电影的信息失败!"

The end ! 

-------------------------我是有底线的 !!-------------------------------------------------

  • 9
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在Python Flask框架中整合多个HTML图形,可以使用以下步骤: 1. 创建一个Flask应用程序,并在应用程序中定义路由和视图函数来处理请求和响应。 2. 在HTML文件中,使用JavaScript或其他图形库(如D3.js)来创建图形,并将其嵌入到HTML中。 3. 在Flask应用程序中,使用render_template函数将多个HTML文件渲染为单个页面。 4. 将HTML文件中的JavaScript代码转移到单独的JavaScript文件中,并将其链接到HTML文件中。 5. 在JavaScript代码中,使用ajax请求从Flask应用程序中获取数据,并使用该数据更新图形。 6. 在Flask应用程序中,使用Flask-SocketIO库来处理实时更新的图形。 7. 使用Flask-SocketIO库的emit函数将数据发送到客户端,并使用JavaScript代码将数据更新到图形中。 8. 在Flask应用程序中,使用Flask-RESTful库来创建RESTful API,允许客户端通过HTTP请求发送和接收数据。 9. 使用JavaScript代码从客户端发送HTTP请求,并使用接收到的数据更新图形。 10. 在Flask应用程序中,使用Flask-Login库来处理用户认证和授权。 11. 根据用户的权限和角色,限制对图形的访问和操作。 12. 在Flask应用程序中,使用Flask-Security库来添加额外的安全功能,如密码哈希和加密。 13. 在Flask应用程序中,使用Flask-Mail库来发送电子邮件通知和警报。 14. 使用定时任务或Flask-Celery库来定期生成和更新图形数据。 总之,要在Python Flask框架中整合多个HTML图形,需要使用多种技术和库,并根据实际需求和场景进行选择和配置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值