Skip to content

Instantly share code, notes, and snippets.

@gordol
Created August 23, 2016 23:31
Show Gist options
  • Save gordol/8f4c7461a03ae6cee9bc3e017ec0e3bf to your computer and use it in GitHub Desktop.
Save gordol/8f4c7461a03ae6cee9bc3e017ec0e3bf to your computer and use it in GitHub Desktop.
Complex Flask-Admin View with custom filters and bulk action
class FilterLowercase(BaseMongoEngineFilter):
def apply(self, query, value):
flt = {'%s__icontains' % self.column: value}
return query.filter(**flt)
def operation(self):
return gettext('contains')
class FilterLowercaseNot(BaseMongoEngineFilter):
def apply(self, query, value):
flt = {'%s__not__icontains' % self.column: value}
return query.filter(**flt)
def operation(self):
return gettext('doesn\'t contain')
class FilterArtistsSimilar(BaseMongoEngineFilter):
def apply(self, query, value):
return query.filter(similar__in=models.Artist.objects(name__icontains=value))
def operation(self):
return gettext('contains')
class FilterArtistsNotSimilar(BaseMongoEngineFilter):
def apply(self, query, value):
return query.filter(similar__nin=models.Artist.objects(name__icontains=value))
def operation(self):
return gettext('doesn\'t contain')
class FilterTags(BaseMongoEngineFilter):
def apply(self, query, value):
return query.filter(tags__in=models.Tag.objects(name__icontains=value))
def operation(self):
return gettext('contains')
class FilterTagsNot(BaseMongoEngineFilter):
def apply(self, query, value):
return query.filter(tags__nin=models.Tag.objects(name__icontains=value))
def operation(self):
return gettext('doesn\'t contain')
class FilterTagsSimilar(BaseMongoEngineFilter):
def apply(self, query, value):
return query.filter(similar__in=models.Tag.objects(name__icontains=value))
def operation(self):
return gettext('contains')
class FilterTagsNotSimilar(BaseMongoEngineFilter):
def apply(self, query, value):
return query.filter(similar__nin=models.Tag.objects(name__icontains=value))
def operation(self):
return gettext('doesn\'t contain')
class FilterArtistsFollowed(BooleanEqualFilter):
def apply(self, query, value):
if value == '1':
return models.Artist.followed()
else:
return models.Artist.unfollowed()
def operation(self):
return gettext('followed')
class ArtistView(ModelView):
column_searchable_list = ('name', 'youtube_user', 'soundcloud_user', 'twitter_user', 'musicbrainz_id', 'facebook_user')
column_list = ('name', 'youtube_user', 'soundcloud_user', 'twitter_user', 'facebook_user', 'discogs_id', 'musicbrainz_id', 'created_on', 'updated_on', 'image', 'active')
form_excluded_columns = ('created_on', 'updated_on', 'image')
allowed_search_types = (StringField, models.LowerStringField)
column_filters = [
FilterLowercase('name', 'Name'), FilterLowercase('soundcloud_user', 'Soundcloud User'), FilterLowercase('twitter_user', 'Twitter User'), FilterLowercase('youtube_user', 'Youtube User'), FilterLowercase('facebook_user', 'Facebook User'),
FilterLowercaseNot('name', 'Name'), FilterLowercaseNot('soundcloud_user', 'Soundcloud User'), FilterLowercaseNot('twitter_user', 'Twitter User'), FilterLowercaseNot('youtube_user', 'Youtube User'), FilterLowercaseNot('facebook_user', 'Facebook User'),
FilterArtistsSimilar('artists', 'Similar Artist Name'),
FilterArtistsNotSimilar('artists', 'Similar Artist Name'),
FilterTags('tags', 'Tag Name'),
FilterTagsNot('tags', 'Tag Name'),
BooleanEqualFilter(models.Artist.active, 'Is Active?'),
FilterArtistsFollowed(models.Artist, 'Is Followed?'),
]
column_formatters = dict(
soundcloud_user = lambda v, c, m, p: m.Markup('<a href="https://soundcloud.com/'+str(m.soundcloud_user)+'">'+str(m.soundcloud_user)+'</a>' if m.soundcloud_user else ''),
twitter_user = lambda v, c, m, p: m.Markup('<a href="https://twitter.com/'+str(m.twitter_user)+'">'+str(m.twitter_user)+'</a>' if m.twitter_user else ''),
youtube_user = lambda v, c, m, p: m.Markup('<a href="https://youtube.com/user/'+str(m.youtube_user)+'">'+str(m.youtube_user)+'</a>' if m.youtube_user else ''),
facebook_user = lambda v, c, m, p: m.Markup('<a href="https://facebook.com/'+str(m.facebook_user)+'">'+str(m.facebook_user)+'</a>' if m.facebook_user else ''),
name = lambda v, c, m, p: m.Markup('<a href="https://www.google.com/search?q=&quot;'+m.name+'&quot;+music+artist">'+m.name+'</a>'),
musicbrainz_id = lambda v, c, m, p: m.Markup('<a href="https://www.musicbrainz.org/artist/'+m.musicbrainz_id+'">'+m.musicbrainz_id+'</a>')
)
form_ajax_refs = {
'similar': {
'fields': ['name'],
'page_size': 15
},
'tags': {
'fields': ['name'],
'page_size': 15
},
'releases': {
'fields': ['name'],
'page_size': 15
}
}
def is_accessible(self):
if current_user.is_authenticated():
return current_user.is_admin
def scaffold_form(self):
form_class = super(ArtistView, self).scaffold_form()
form_class.name = TextField('Artist Name')
form_class.soundcloud_user = TextField('SoundCloud Username')
form_class.youtube_user = TextField('Youtube Username')
form_class.facebook_user = TextField('FacebookUsername')
form_class.twitter_user = TextField('Twitter Username')
form_class.musicbrainz_id = TextField('Musicbrainz ID')
return form_class
@action('toggle',
lazy_gettext('Toggle'),
lazy_gettext('Are you sure you want to toggle the selected items?'))
def action_toggle(self, ids):
try:
count = 0
for id in ids:
artist = models.Artist.objects.get(pk=id)
if artist.active:
artist.active = False
else:
artist.active = True
artist.save()
count += 1
flash(ngettext('Item was successfully toggled.',
'%(count)s items were successfully toggled.',
count,
count=count))
except Exception, ex:
flash(gettext('Failed to toggle items. %(error)s', error=str(ex)), 'error')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment