Как перечислить все ресурсы, принадлежащие одному пользователю в flask-appbuilder, а не все?

Я кратко просмотрел документ для flask-appbuilder. В большинстве примеров ModelView перечисляет все ресурсы. Если есть связанные представления, FAB позволяет администратору (пользователю) проверять детали связанных элементов согласно их определениям отношений.

Тем не менее, я понятия не имею, как отобразить ресурсы, принадлежащие текущим пользователям. В других средах это легко реализовать с помощью пользовательских SQL-запросов (оператор where). Но я не нашел демонстрационный проект с SQL-запросами из примеров FAB, за исключением некоторого кода вставки тестовой даты в базу данных.

Например, давайте представим проект, связанный с IoT. Владельцы имеют много устройств, и одно устройство может использоваться многими пользователями. Следовательно,

  • как администратор, он / она должен видеть все устройства.
  • как владелец, он / она должен видеть все принадлежащие ему устройства.
  • как пользователи, он / она должен видеть все устройства, которые он / она может использовать.

models.py

class Account(Model):
    id = Column(Integer, primary_key = True)
    username = Column(String(128), unique = True)
    password = Column(String(128))
    email = Column(String(128))
    cellphone = Column(String(32))

    def __repr__(self):
        return self.username

class Device(Model):
    id = Column(Integer, primary_key = True)
    snr = Column(String(256), unique = True)
    name = Column(String(128))
    addr = Column(String(256))
    latitude = Column(Float)
    longitude = Column(Float)
    status = Column(Enum('init','normal','transfer','suspend'), default = 'init')
    owner_id = Column(Integer, ForeignKey('account.id'))    
    owner = relationship("Account")

    def __repr__(self):
        return self.name

class Access(Model):
    id = Column(Integer, primary_key = True)
    name = Column(String(128))
    submit = Column(Date)
    approve = Column(Date)
    status = Column(Enum('init','approve','reject','expire'), default='init')
    dev_id = Column(Integer, ForeignKey('device.id'))
    device = relationship("Device")
    user_id = Column(Integer, ForeignKey('account.id'))    
    user = relationship("Account")

    def __repr__(self):
        return self.name

views.py

class AccessView(ModelView):
    datamodel = SQLAInterface(Access)

    label_columns = {}
    list_columns = ['device','owner','submit','approve']    

class DeviceView(ModelView):        
    datamodel = SQLAInterface(Device)
    related_views = [ApplicationView, EventView]

    label_columns = {'snr':'SNR', 
        'owner_id':'Owner'}
    list_columns = ['name','snr','addr','owner']
    edit_columns = ['name','snr','owner','addr','latitude','longitude','status']
    add_columns = edit_columns

    show_fieldsets = [
        ('Summary',
            {'fields':['name','snr','owner']}
        ),
        ('Device Info',
            {'fields':['addr','latitude','longitude','status'],'expanded':True}
        ),
    ]

@expose('/mine')
def mine(self):
    msg = "Mine Assets"
    return self.render_template('testpage.html', msg = msg)

@expose('/granted')
def granted(self):
    msg = "Granted Assets"
    return self.render_template('testpage.html', msg = msg)

db.create_all()

appbuilder.add_view(DeviceView,
    "My Devices",
    icon = "fa-heart",
    category = "Devices",
    category_icon = "fa-microchip")

appbuilder.add_view(AccountView,
    "Account",
    icon = "fa-group",
    category = "Devices")

appbuilder.add_view(AccessView,
    "Access",
    icon = "fa-handshake-o",
    category = "Devices")

Если мы определили следующие URL для трех представлений:

  • admin, / deviceview / list
  • владелец, / deviceview / mine
  • пользователь, / deviceview / предоставлено

Тем не менее, я понятия не имею, как писать методы мои / предоставлено. Используя db.session.query()?

db.session.query(устройство, владелец = владелец) или db.session.query(доступ, пользователь = пользователь)

Или какой-нибудь документ, который я еще не читал?

1 ответ

Я нахожу одно решение для этого, по крайней мере, частичный ответ. Помимо DeviceView для администратора, я определил еще один DeviceXView (как временное имя) в качестве списка устройств для текущего пользователя и с помощью base_filter для сужения набора данных из Model.

class DeviceXView(ModelView):        
    datamodel = SQLAInterface(Device)
    base_filters = [['owner', FilterEqualFunction, get_user],]
    related_views = [ApplicationView, EventView]

    label_columns = {'snr':'SNR', 
        'api_dev_id':'Device ID', 
        'api_dev_key':'Device Key',
        'api_id':'API ID',
        'api_key':'API Key',
        'owner_id':'Owner'}
    list_columns = ['name','snr','addr','owner']
    edit_columns = ['name','snr','owner','addr','latitude','longitude','status','api_id','api_key','api_dev_id','api_dev_key']
    add_columns = edit_columns

    show_fieldsets = [
        ('Summary',
            {'fields':['name','snr','owner']}
        ),
        ('Device Info',
            {'fields':['addr','latitude','longitude','status','api_id','api_key','api_dev_id','api_dev_key'],'expanded':True}
        ),
    ]

Это для всех устройств, принадлежащих текущему пользователю. Чтобы отобразить все устройства, к которым пользователь имеет доступ, мы можем определить AccessView и DeviceView как связанные View.

Другие вопросы по тегам