Flask security 在 Flask admin 上分离访问数据
flask security separating access data on flask admin
我有一个用 flask 构建的寄宿家庭预订应用程序..
每个寄宿家庭都有一个用户登录名,这个登录名是用 flask-security 构建的,每个寄宿家庭的主人都有角色 User。
每个用户都可以使用 flask-admin 输入他们的寄宿家庭数据。
但不幸的是,如果用户输入了他们的数据,其他具有角色 User 的用户也可以看到数据也有输入..
所以..我的问题是如果用户具有相同的角色,如何分离数据..?
用户A只能看到他的数据,用户B也是..
这是我的models.py代码:
roles_users = database.Table(
'roles_users',
database.Column('user_id', database.Integer(), database.ForeignKey('user.id')),
database.Column('role_id', database.Integer(), database.ForeignKey('role.id'))
)
class Role(database.Model, RoleMixin):
id = database.Column(database.Integer(), primary_key=True)
name = database.Column(database.String(80), unique=True)
description = database.Column(database.String(255))
def __str__(self):
return self.name
class User(database.Model, UserMixin):
id = database.Column(database.Integer, primary_key=True)
first_name = database.Column(database.String(255))
last_name = database.Column(database.String(255))
email = database.Column(database.String(255), unique=True)
password = database.Column(database.String(255))
active = database.Column(database.Boolean())
confirmed_at = database.Column(database.DateTime())
roles = database.relationship('Role', secondary=roles_users,
backref=database.backref('users', lazy='dynamic'))
def __str__(self):
return self.email
class Room(database.Model):
__tablename__ = 'room'
room_id = Column(Integer, primary_key=True)
room_name = Column(String)
room_description = Column(String)
room_images = Column(database.Unicode(128))
room_price = Column(Integer)
user_id = Column(Integer, ForeignKey(User.id))
这是我的 views.py :
class UserAccess(ModelView):
def is_accessible(self):
if not current_user.is_active or not current_user.is_authenticated:
return False
if current_user.has_role('user'):
return True
return False
def _handle_view(self, name, **kwargs):
"""
Override builtin _handle_view in order to redirect users when a view is not accessible.
"""
if not self.is_accessible():
if current_user.is_authenticated:
# permission denied
abort(403)
else:
# login
return redirect(url_for('security.login', next=request.url))
class Room(UserAccess):
form_overrides = dict(keterangan_kamar=CKEditorField)
create_template = 'admin/ckeditor.html'
edit_template = 'admin/ckeditor.html'
column_list = ('room_name', 'room_images', 'room_price')
def _list_thumbnail(view, context, model, name):
if not model.room_images:
return ''
return Markup('<img src="%s">' % url_for('static',
filename=form.thumbgen_filename(model.room_images)))
column_formatters = {
'room_images': _list_thumbnail
}
# Alternative way to contribute field is to override it completely.
# In this case, Flask-Admin won't attempt to merge various parameters for the field.
form_extra_fields = {
'room_images': form.ImageUploadField('Room Images',
base_path=file_path,
thumbnail_size=(100, 100, True))
}
您需要通过覆盖 get_query
and get_count_query
向 Room
视图添加永久过滤器
例如(请注意我已将您的 Room
class 命名为 RoomView
因为您已经有一个名为 Room
的 class 代表数据库模型):
class RoomView(UserAccess):
def get_query(self):
return self.session.query(self.model).filter(
Room.user_id == current_user.id
)
def get_count_query(self):
return self.session.query(func.count('*')).select_from(self.model).filter(
Room.user_id == current_user.id
)
# ... your code etc
我有一个用 flask 构建的寄宿家庭预订应用程序.. 每个寄宿家庭都有一个用户登录名,这个登录名是用 flask-security 构建的,每个寄宿家庭的主人都有角色 User。 每个用户都可以使用 flask-admin 输入他们的寄宿家庭数据。 但不幸的是,如果用户输入了他们的数据,其他具有角色 User 的用户也可以看到数据也有输入..
所以..我的问题是如果用户具有相同的角色,如何分离数据..? 用户A只能看到他的数据,用户B也是..
这是我的models.py代码:
roles_users = database.Table(
'roles_users',
database.Column('user_id', database.Integer(), database.ForeignKey('user.id')),
database.Column('role_id', database.Integer(), database.ForeignKey('role.id'))
)
class Role(database.Model, RoleMixin):
id = database.Column(database.Integer(), primary_key=True)
name = database.Column(database.String(80), unique=True)
description = database.Column(database.String(255))
def __str__(self):
return self.name
class User(database.Model, UserMixin):
id = database.Column(database.Integer, primary_key=True)
first_name = database.Column(database.String(255))
last_name = database.Column(database.String(255))
email = database.Column(database.String(255), unique=True)
password = database.Column(database.String(255))
active = database.Column(database.Boolean())
confirmed_at = database.Column(database.DateTime())
roles = database.relationship('Role', secondary=roles_users,
backref=database.backref('users', lazy='dynamic'))
def __str__(self):
return self.email
class Room(database.Model):
__tablename__ = 'room'
room_id = Column(Integer, primary_key=True)
room_name = Column(String)
room_description = Column(String)
room_images = Column(database.Unicode(128))
room_price = Column(Integer)
user_id = Column(Integer, ForeignKey(User.id))
这是我的 views.py :
class UserAccess(ModelView):
def is_accessible(self):
if not current_user.is_active or not current_user.is_authenticated:
return False
if current_user.has_role('user'):
return True
return False
def _handle_view(self, name, **kwargs):
"""
Override builtin _handle_view in order to redirect users when a view is not accessible.
"""
if not self.is_accessible():
if current_user.is_authenticated:
# permission denied
abort(403)
else:
# login
return redirect(url_for('security.login', next=request.url))
class Room(UserAccess):
form_overrides = dict(keterangan_kamar=CKEditorField)
create_template = 'admin/ckeditor.html'
edit_template = 'admin/ckeditor.html'
column_list = ('room_name', 'room_images', 'room_price')
def _list_thumbnail(view, context, model, name):
if not model.room_images:
return ''
return Markup('<img src="%s">' % url_for('static',
filename=form.thumbgen_filename(model.room_images)))
column_formatters = {
'room_images': _list_thumbnail
}
# Alternative way to contribute field is to override it completely.
# In this case, Flask-Admin won't attempt to merge various parameters for the field.
form_extra_fields = {
'room_images': form.ImageUploadField('Room Images',
base_path=file_path,
thumbnail_size=(100, 100, True))
}
您需要通过覆盖 get_query
and get_count_query
Room
视图添加永久过滤器
例如(请注意我已将您的 Room
class 命名为 RoomView
因为您已经有一个名为 Room
的 class 代表数据库模型):
class RoomView(UserAccess):
def get_query(self):
return self.session.query(self.model).filter(
Room.user_id == current_user.id
)
def get_count_query(self):
return self.session.query(func.count('*')).select_from(self.model).filter(
Room.user_id == current_user.id
)
# ... your code etc