Search code examples
flasksqlalchemyflask-sqlalchemycrudflask-admin

Flask Admin - Restrict CRUD functions for own user content


I am wondering if there is somebody out there who has successfully restricted the CRUD functions from flask admin. Or if this is the right tool at all.

What I would like to do is to transform the ModelViews in a way so that a user can only edit the own content. Example: A database table "restaurant menu" contains the dishes offered from different restaurants. If a restaurant wishes to change something, they should be able to change and view their own content but not the content of the other restaurants. Ideally, there is an easy way with sqlalchemy - where I first query a "User" model and get the associated restaurants with the users and then pass it to the ModelView class.

Is there an easy implementation of doing such a thing or are there other CMS system which can handle such a function more easily?


Solution

  • So, I went through the source code a bit more deeply. Many thanks to gittert for the help.

    Note that within my solution, I do want to restrict the View and Editing function for one particular column, which is also a foreign key from a different table.

    So in order to restrict the view functions I did overwrote the get_query() and get_count_query() as it was posted in previous posts:

    ##  overwrite
    def get_query(self):
        self._auto_fush_deactivate()
        return super(CustomView, 
    self).get_query().filter(User.id== 1)
    
    def get_count_query(self):
        return self.session.query(func.count('*')).filter(User.id == 1)
    

    and to manipulate that the user can only add new data using his OWN foreign key in the table I additionally overwrote the on_model_create() function.

    def on_model_change(self, form, model, is_created):
    
        ### deactivate auto_flush temp. to not receive data integrity error
        self._auto_fush_deactivate()
        ### create model from table user
        overwrite_model = self.session.query(User).filter(User.id== 1).first()
    
        ### overwrite the user id with model from User-Model
        model.user_id =  overwrite_model
        self._auto_fush_activate()
    
    def _auto_fush_deactivate(self):
        self.session.autoflush = False
    
    def _auto_fush_activate(self):
        self.session.autoflush = True