Skip to content

Instantly share code, notes, and snippets.

@riteshreddyr
Last active July 19, 2021 07:21
Show Gist options
  • Star 13 You must be signed in to star a gist
  • Fork 5 You must be signed in to fork a gist
  • Save riteshreddyr/73404faf44dafa2be2f0 to your computer and use it in GitHub Desktop.
Save riteshreddyr/73404faf44dafa2be2f0 to your computer and use it in GitHub Desktop.
Flask-admin Many-to-Many Search and Filtering

#Flask-admin Many-to-Many Search

Many-to-Many searches are not easily supported by Flask-admin. Read Here for more info

##Solution

  • Add the association tables to the list of join tables so that the join between the two tables can be made through the association table.
  • Reverse the tables to ensure that the association tables are processed before the other join table.

Tested on Flask-Admin 1.1.0

class Post( Base ):
    __tablename__ = 'posts'
    id = Column( Integer, primary_key=True )
    title = Column( Unicode( 255 ), nullable=False )
    tags = relationship( 'Tag', backref='posts', secondary='taxonomy' )

class Tag( Base ):
    __tablename__ = 'tags'
    id = Column( Integer, primary_key=True )
    name = Column( Unicode( 255 ), nullable=False )

taxonomy = Table(
    'taxonomy', Base.metadata,
    Column( 'post_id', Integer, ForeignKey( 'posts.id' ) ),
    Column( 'tag_id', Integer, ForeignKey( 'tags.id' ) ),
)
 class PostModelView( ModelView ):
        column_searchable_list = ( Post.title, Tag.name )
        column_filters = (Post.title, Tag.name)
        
        def init_search( self ):
            r = super( PostModelView, self ).init_search()
            #add the association table to search join list
            self._search_joins.append(taxonomy)
            #reverse the lsit so that the association table appears before the two main tables
            self._search_joins.reverse()
            return r
            
        def scaffold_filters(self, name):
            filters = super( PostModeView, self).scaffold_filters(name)
            #Check if "tags" table has been processed and the join table added
            if "tags" in self._filter_joins:
              #add the association table to the filter join tables
              self._filter_joins['tags'].append(taxonomy)
              #reverse the list so that the association table appears before the two main tables
              self._filter_joins['tags'].reverse()
            
            return filters
              
@VoittajaTomi
Copy link

Hi! Do you know how this works with current flask-admin version? I am having trouble implementing tags. I am getting
AttributeError: 'MySpecialModelView' object has no attribute '_search_joins'

@miaohf
Copy link

miaohf commented Mar 24, 2019

I've get this error too.

@acarkaan
Copy link

acarkaan commented Sep 8, 2020

same error

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment