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

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

1.定义

“一对多”是指关系型数据库中的模型对象的一对多的模型关系,它表示一个模型(即表)的一条记录(即行)对应多个另一个模型(即另一个表)的记录。简单来说,一个模型中的一个记录关联另一个模型中的多个记录。比如一个班级对象有多个学生对象。

以班级对象以及学生对象为例写个代码

# 班级模型
class Grade(db.Model):
    __tablename__ = 'grade'  # 班级表名
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    grade_name = db.Column(db.String(30), unique=True)  # 班级名称

    """
    建立关联
    第一个参数:关联的模型名(表)
    第二个参数:反向引用的名称,grade对象,让student反过来得到grade对象的名称:student.grade
    第三个参数:懒加载
    """
    students = db.relationship('Student', backref='grade', lazy=True)


# 学生模型
class Student(db.Model):
    __tablename__ = 'student'  # 学生表名
    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    student_name = db.Column(db.String(30), unique=True)  # 学生名字
    age = db.Column(db.Integer, default=1)  # 学生年龄,默认1岁
    # 外键:跟Grade对象的id关联
    gradeid = db.Column(db.Integer, db.ForeignKey(Grade.id))

关键点:

(1)外键是在一对多中的多的一方,原因是为了方便数据的处理,加入把外键放在“一”这一方,就会出现班级模型对象中的外键某行的值会有多个学生id,在进行数据操作时候还得查找出来具体的学生id去关联学生对象模型的学生数据,这样就显得比较麻烦;

(2)在主键对象模型上建立关联属性,在此例子中就是“students = db.relationship('Student', backref='grade', lazy=True)” ,这样做的好处就是可以通过班级对象查找出对于的学生数据,也可以通过学生对象反向查找出班级数据.

2.数据操作

在进行数据迁移操作之后就可以看到相应的数据表了

(1)增

a.增加班级数据

@user_bp.route("/addgrad")
def add_grade():
    # 班级列表
    grade_list = []
    for i in range(10):
        # 班级名
        grd = Grade()
        grd.grade_name = f'终极{i}班'
        grade_list.append(grd)

    try:
        # 添加班级列表
        db.session.add_all(grade_list)
        db.session.commit()
        return "添加班级成功!"
    except:
        db.session.rollback()  # 回滚

b.添加学生

@user_bp.route("/addstu")
def add_student():
    # 学生列表
    student_list = []
    for i in range(20):
        # 学生名
        std = Student()
        std.student_name = f'jason{i}-{random.randint(15,99)}'
        std.age = random.randint(15,18)
        std.gradeid = random.randint(5,8)
        student_list.append(std)

    try:
        # 添加学生列表
        db.session.add_all(student_list)
        db.session.commit()
        return "添加学生成功!"
    except:
        db.session.rollback()  # 回滚

(2)删

删除班级信息

@user_bp.route("/delgrd/<int:grd_id>")
def del_grd(grd_id):
    grd_obj = Grade.query.get(grd_id)
    try:
        # 删除班级
        db.session.delete(grd_obj)
        db.session.commit()
        return "删除班级信息成功!"
    except:
        db.session.rollback()  # 回滚
        return "删除班级信息失败!"

删除学生信息

@user_bp.route("/delstu/<int:stu_id>")
def del_std(stu_id):
    stu_obj = Grade.query.get(stu_id)
    try:
        # 删除学生
        db.session.delete(stu_obj)
        db.session.commit()
        return "删除学生信息成功!"
    except:
        db.session.rollback()  # 回滚
        return "删除学生信息失败!"

如图所示,删除了id为6的学生

(3)改

①更改班级信息

@user_bp.route("/updgra")
def update_grad():
    # 将前两个id的班级名称的前两个字变为“终极”
    try:
        for i in range(1, 3):
            g = Grade.query.get(i)
            g_name = g.grade_name
            g.grade_name = g_name.replace(g_name[:2], '终极')
            db.session.commit()
        return "更新班级信息成功!"
    except:
        db.session.rollback()  # 回滚
        print(traceback.format_exc())
        return "更新班级信息失败!"

②更改学生信息

@user_bp.route("/updstu")
def update_stu():
    # 将年龄小于18岁的学生的年龄改为18岁
    stu_obj = Student.query.filter(Student.age.__lt__(18))

    try:
        for s in stu_obj:
            s.age = 18
        db.session.commit()
        return "更新学生信息成功!"
    except:
        db.session.rollback()  # 回滚
        print(traceback.format_exc())
        return "更新学生信息失败!"

(4)查

查询班级信息

@user_bp.route("/getgra")
def get_gra():
    # 查询终极5班有多少个学生
    count_stu = Student.query.filter(Student.gradeid == Grade.query.filter(Grade.grade_name == "终极5班").first().id).count()
    try:
        return f"终极5班有{count_stu}个学生"
    except:
        db.session.rollback()  # 回滚
        print(traceback.format_exc())
        return "查询终极5班的学生人数失败!"

查询学生信息

@user_bp.route("/getstu")
def get_stu():
    # 查询id为18的学生属于哪个班级
    gra_info = Student.query.get(18).grade.grade_name
    try:
        return f"id为18的学生属于{gra_info}!"
    except:
        db.session.rollback()  # 回滚
        print(traceback.format_exc())
        return f"查询id为18的学生的班级失败!"

The end !Thanks

  • 6
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值