Reputation: 3039
I have an app making by Flask and for database management I using Flask-admin and Flask-SQLAlchemy. And in my app there has three role, which is:
here is the snipet of code on my table:
roles_users = db.Table(
'roles_users',
db.Column('user_id', db.Integer(), db.ForeignKey('user.id')),
db.Column('role_id', db.Integer(), db.ForeignKey('role.id'))
)
class Role(db.Model, RoleMixin):
id = db.Column(db.Integer(), primary_key=True)
name = db.Column(db.String(80), unique=True)
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(255))
roles = db.relationship('Role', secondary=roles_users,
backref=db.backref('users', lazy='dynamic'))
class School(User):
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
class Parent(User):
id = db.Column(db.Integer, primary_key=True)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
school_id = db.Column(db.Integer, db.ForeignKey('school.id'))
The code already works fine.
I can set the role for all of the users manually with Flask-admin interface, I can make it with a user that has admin role.
But, for the user that has school role, I don't give access to set the role like admin does.
What I want is when the user that has school role make an account, it automatically set the role to parent.
In my ModelView, I try to insert it with this code:
class ParentModelView(sqla.ModelView):
def on_model_change(self, form, model, is_created):
if is_created:
model.school_id = current_user.id
model.roles = 'parent'
and then I got this error:
TypeError: Incompatible collection type: str is not list-like
and then I try to wraping it with list:
def on_model_change(self, form, model, is_created):
if is_created:
model.school_id = current_user.id
model.roles = ['parent']
then the error be like this:
AttributeError: 'str' object has no attribute '_sa_instance_state'
And when I try to set the default value on my relationship column :
class User(db.Model, UserMixin):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(255))
roles = db.relationship('Role', secondary=roles_users,
backref=db.backref('users', lazy='dynamic'),
default='parent') # or default=3 (which is '3' is the parent id in roles_user association table.
and then I got this error:
TypeError: relationship() got an unexpected keyword argument 'default'
So, the point what I want is to set a default value on my relationship column that defines roles users.
Any help will be much appreciated.
Upvotes: 3
Views: 2784
Reputation: 8046
In your code you are trying to assign the string 'parent' when you should be assigning a list of Role
instances.
In your on_model_change
method you need to fetch the role that has name 'Parent' from the database and then assign it to the roles relationship as a list.
Example (untested)
def on_model_change(self, form, model, is_created):
if is_created:
# find the role with name 'Parent'
_parent_role = Role.query.filter(Role.name == 'Parent').first()
if _parent_role:
model.school_id = current_user.id
model.roles = [_parent_role]
Upvotes: 4