Flask 数据库多对多关系
                        
                            时间:2021-07-01 10:21:17
                            帮助过:22人阅读
							                        
                     
                    
                    
                    
 
- registrations = db.Table(‘registrations‘,  
-     db.Column(‘student_id‘, db.Integer, db.ForeignKey(‘students.id‘)),  
-     db.Column(‘class_id‘, db.Integer, db.ForeignKey(‘classes.id‘))  
- )  
-   
-   
- class Student(db.Model):  
-     id = db.Column(db.Integer, primary_key=True)  
-    name = db.Column(db.String)  
-    classes = db.relationship(‘Class‘,secondary=registrations,  
-                                     backref=db.backref(‘students‘, lazy=‘dynamic‘),  
-                                     lazy=‘dynamic‘)  
-   
-   
- class Class(db.Model):  
-     id = db.Column(db.Integer, primary_key = True)  
-     name = db.Column(db.String)  
        多对多关系仍使用定义一对多关系的 db.relationship() 方法进行定义,但在多对多关系中,必须把 secondary 参数设为关联表。多对多关系可以在任何一个类中定义, backref 参数会处理好关系的另一侧。关联表就是一个简单的表,不是模型,SQLAlchemy 会自动接管这个表。
       这样处理多对多关系特别简单。假设学生是 s,课程是 c,学生注册课程的代码为:
>>> s.classes.append(c)
>>> db.session.add(s)
列出学生 s 注册的课程以及注册了课程 c 的学生也很简单:
>>> s.classes.all()
>>> c.students.all()
Class 模型中的 students 关系由参数 db.backref() 定义。注意,这个关系中还指定了 lazy= ‘dynamic‘ 参数,所以关系两侧返回的查询都可接受额外的过滤器。
如果后来学生 s 决定不选课程 c 了,那么可使用下面的代码更新数据库:
>>> s.classes.remove(c)
下面来看一个实际的例子:因为在设计中学生会转学院,所以,学生与学院是多对多的关系
1.定义模型
 
[python] view plain
 copy
 
- class User(UserMixin, db.Model):  
-     __tablename__ = ‘users‘  
-     id = db.Column(db.Integer, primary_key=True)  
-     email = db.Column(db.String(100), unique=True, index=True)  
-       
-     .............省略其他字段  
-     departments=db.relationship(‘Department‘, secondary=user_department, backref=db.backref(‘users‘,lazy=‘dynamic‘), lazy=‘dynamic‘)  
-       
 
[python] view plain
 copy
 
- class Department(db.Model):  
-     __tablename__ = ‘departments‘  
-     id = db.Column(db.Integer, primary_key=True)  
-     department = db.Column(db.String(100))  
 
[python] view plain
 copy
 
- user_department = db.Table(‘user_department‘,  
-     db.Column(‘user_id‘, db.Integer, db.ForeignKey(‘users.id‘), primary_key=True),  
-     db.Column(‘department_id‘, db.Integer, db.ForeignKey(‘departments.id‘), primary_key=True)    
- )  
2.定义表单:
 
 
[python] view plain
 copy
 
- class SmForm(Form):  
-     name = StringField(‘真实姓名‘, validators=[Length(0, 64)])  
-     ....................省略其他字段  
-     is_departmentChange = BooleanField(‘是否转过学院‘)  
-     pre_department = SelectField(‘原学院:‘, coerce=int)  
-     cut_department = SelectField(‘现学院:‘, coerce=int)  
-       
-     submit = SubmitField(‘Submit‘)  
-   
-    
-     def __init__(self, user, *args, **kwargs):  
-         super(SmForm, self).__init__(*args, **kwargs)  
-         <strong>self.pre_department.choices = [(pre_department.id, pre_department.department)  
-                              for pre_department in Department.query.order_by(Department.department).all()]  
-         self.cut_department.choices = [(cut_department.id, cut_department.department)  
-                              for cut_department in Department.query.order_by(Department.department).all()]</strong>  
-          
-         self.user = user  
3.定义路由:
 
 
[python] view plain
 copy
 
- @main.route(‘/sm‘, methods=[‘GET‘, ‘POST‘])  
- @login_required  
- @main.errorhandler(404)  
- def sm():  
-     user = User.query.filter_by(email=current_user.email).first()  
-     form = SmForm(user)  
-     if  user.is_realname ==False:  
-         if form.validate_on_submit():  
-   
-             
-             usr = current_user._get_current_object()  
-             deparment = user.departments.all()  
-             for de in deparment:  
-                 de.users.remove(usr)</strong>  
-   
-        ........................省略其他  
-   
-               
-             user.is_departmentChange = form.is_departmentChange.data  
-           <strong>
-             user.departments.append(Department.query.get(form.pre_department.data))  
-             user.departments.append(Department.query.get(form.cut_department.data))  
-   
-             db.session.add(user)  
-             db.session.commit()</strong>  
-             return redirect(url_for(‘.sm_success‘))  
-     return render_template(‘sm.html‘, form=form)  
4.渲染模板(省略)
Flask 数据库多对多关系
标签:field   课程   hand   copyto   jsb   classes   有一个   string   login