Ограничение одного представления на Flask-Admin?

У меня есть один файл для приложения Flask, views.py.

Внутри views.py у меня есть настройка для Flask-Admin и соответствующая база данных sqlalchemy здесь:

db = SQLAlchemy(flaskapp)

def build_db():

import random
import datetime

db.drop_all()
db.create_all()

# Create sample Users
testuser = []
testgroup = []
testlevel = []

user_list = []
for i in range(len(testuser)):
    user = User()
    user.testuser = testuser[i]
    user.testlevel = testlevel[i]
    user.testgroup = testgroup[i]

    user_list.append(user)
    db.session.add(user)

for user in user_list:
    entry = random.choice(sample_text)  # select text at random
    post = Post()
    post.user = user
    post.title = entry['title']
    post.text = entry['content']
    tmp = int(1000*random.random())  # random number between 0 and 1000:
    post.date = datetime.datetime.now() - datetime.timedelta(days=tmp)
    post.tags = random.sample(tag_list, 2)  # select a couple of tags at random
    db.session.add(post)

db.session.commit()
return

# Create models
class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    testuser = db.Column(db.String(100))
    testgroup = db.Column(db.String(100))
    testlevel = db.Column(db.String(100))

# Required for administrative interface. For python 3 please use __str__ instead.
def __repr__(self):
    return self.testuser

class UserInfo(db.Model):
    id = db.Column(db.Integer, primary_key=True)

    key = db.Column(db.String(64), nullable=False)
    value = db.Column(db.String(64))

    user_id = db.Column(db.Integer(), db.ForeignKey(User.id))
    user = db.relationship(User, backref='info')

def __repr__(self):
    return '%s - %s' % (self.key, self.value)

### Attempt at doing something...
class MyView(ModelView):
    @expose('/admin/userview', methods=('GET', 'POST'))
    def adminview():
        return "yes"
##ADMIN
admin = Admin(flaskapp, name="Test Aptly")
admin.add_view(MyView(User, db.session))

Вопрос.

Как заблокировать доступ к странице «/admin/userview» в зависимости от уровня пользователя (определяется с помощью базы данных «testlevel»)? У пользователей есть 3 качества. Примером для двух пользователей может быть:

testuser          testgroup        testlevel

joe               it               admin

john              dev              basic

Как бы я мог ограничить страницу администратора, чтобы разрешить только людям с testlevel="admin"? Использую ли я Flask-Security? Колба-Директор? Если да, то как? Я немного возился с обоими, и у меня пока ничего не получилось.

Вот пример «/admin/userview»: пример Flask-Admin

Прежде всего, вы можете использовать различные свойства уровня класса для настройки того, что должно отображаться и как. Например, column_list можно использовать для отображения некоторых столбцов или включения дополнительных столбцов из связанных моделей.

Например:

class UserView(ModelView):
    # Show only name and email columns in list view
    column_list = ('name', 'email')

    # Enable search functionality - it will search for terms in
    # name and email fields
    column_searchable_list = ('name', 'email')

    # Add filters for name and email columns
    column_filters = ('name', 'email')

Кроме того, вы можете переопределить некоторые методы ModelView и реализовать собственную логику.

Например, если вам нужно добавить дополнительное поле в сгенерированную форму, вы можете сделать что-то вроде этого:

class UserView(ModelView):
    def scaffold_form(self):
        form_class = super(UserView, self).scaffold_form()
        form_class.extra = wtf.TextField('Extra')
        return form_class

Проверьте документацию flask.ext.admin.contrib.sqlamodel для список свойств и методов конфигурации. Спасибо!


person asdfgthereisnocowlevel    schedule 14.07.2014    source источник


Ответы (1)


Я предполагаю, что вы создали подкласс BaseView для создания административного представления и используете Flask-login.

Затем переопределите метод is_accessible в вашем классе просмотра, чтобы проверить качество текущего пользователя:

from flask.ext.admin.base import BaseView
from flask.ext.login import current_user

class MyView(BaseView):
    def is_accessible(self):
        return current_user.testlevel == 'admin'

Надеюсь это поможет!

person rkz_io    schedule 14.07.2014
comment
Я также должен был указать, что я использую kerberos для получения имени пользователя, например: request.environ.get('REMOTE_USER') Я ничего не подклассифицировал, я разместил там все, что использовал для запуска и запуска Flask-Admin/sqlalchemy. Я понятия не имею, где Flask-Admin хранит свои веб-страницы или что-то еще :/ - person asdfgthereisnocowlevel; 14.07.2014
comment
Если request.environ.get('REMOTE_USER') содержит имя пользователя (в виде строки), вы можете запросить свою базу данных, чтобы получить его тестовый уровень. Что касается подклассов, должно быть какое-то место, где вы создаете объект Admin и добавляете к нему представления (пример здесь). Какой класс вы используете в admin.add_view(...)? - person rkz_io; 14.07.2014
comment
Да, я делал это во всем приложении Flask, но с помощью Flask-Admin мне не удалось заставить его работать с запросами к базе данных. - person asdfgthereisnocowlevel; 14.07.2014
comment
Можете ли вы отредактировать свой вопрос с кодом, который у вас есть для инициализации Flask-Admin? Поможет выяснить, почему вы не можете выполнять запросы именно с помощью Flask-Admin. - person rkz_io; 14.07.2014
comment
Не позволяйте мне редактировать, но в нижней части приведенного выше кода показано, как я инициализирую Flask-Admin admin = Admin(flaskapp, name="Test Aptly") admin.add_view(MyView(User, db.session)) - person asdfgthereisnocowlevel; 14.07.2014
comment
Просмотрите свой код, чтобы найти, где объявлен класс MyView. Поскольку вы создаете его с помощью session, я думаю, он является подклассом ModelView. В таком представлении вы можете получить доступ к сеансу базы данных с помощью self.session, отсюда вы можете запросить соответствующий User (self.session.query(User).filter(...)) и проверить, имеет ли он право testlevel. - person rkz_io; 15.07.2014