Created
August 23, 2016 23:31
-
-
Save gordol/8f4c7461a03ae6cee9bc3e017ec0e3bf to your computer and use it in GitHub Desktop.
Complex Flask-Admin View with custom filters and bulk action
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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="'+m.name+'"+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