Use prefetch/select related to optimize. Cleanup.

This commit is contained in:
Josh W 2020-03-10 14:53:13 -04:00
parent 518887e82a
commit 17f79d2a4c

View file

@ -6,9 +6,10 @@ from inline_actions.admin import (
InlineActionsMixin, InlineActionsModelAdminMixin InlineActionsMixin, InlineActionsModelAdminMixin
) )
from core.utils import quantify
from profiles.actions import RequestSongActionMixin, ToggleFavoriteActionsMixin
from .actions import change_items, publish_items, remove_items from .actions import change_items, publish_items, remove_items
from .models import Album, Artist, Game, Song, Store from .models import Album, Artist, Game, Song, Store
from profiles.actions import RequestSongActionMixin, ToggleFavoriteActionsMixin
class BaseSongInline(RequestSongActionMixin, class BaseSongInline(RequestSongActionMixin,
@ -243,7 +244,6 @@ class StoreAdmin(admin.ModelAdmin):
@admin.register(Song) @admin.register(Song)
class SongAdmin(RequestSongActionMixin, class SongAdmin(RequestSongActionMixin,
ToggleFavoriteActionsMixin,
InlineActionsModelAdminMixin, InlineActionsModelAdminMixin,
admin.ModelAdmin): admin.ModelAdmin):
formfield_overrides = { formfield_overrides = {
@ -258,9 +258,10 @@ class SongAdmin(RequestSongActionMixin,
'_is_enabled', '_is_enabled',
'_is_published', '_is_published',
'_is_requestable') '_is_requestable')
list_select_related = True list_select_related = ('album', 'game')
search_fields = ['title'] search_fields = ['title']
actions = ['publish_songs', actions = ['publish_songs',
'add_favorites', 'remove_favorites',
'add_game', 'remove_game', 'add_game', 'remove_game',
'add_album', 'remove_album', 'add_album', 'remove_album',
'add_artists', 'remove_artists'] 'add_artists', 'remove_artists']
@ -300,18 +301,29 @@ class SongAdmin(RequestSongActionMixin,
) )
inlines = [ArtistInline, StoreInline] inlines = [ArtistInline, StoreInline]
def get_queryset(self, request):
qs = super().get_queryset(request)
return qs.prefetch_related('artists', 'stores')
def formfield_for_foreignkey(self, db_field, request, **kwargs): def formfield_for_foreignkey(self, db_field, request, **kwargs):
if db_field.name == 'active_store': if db_field.name == 'active_store':
# New songs won't have an 'object_id' until they are saved for the
# first time. So on new songs, force an empty QuerySet.
try:
kwargs['queryset'] = Store.objects.filter( kwargs['queryset'] = Store.objects.filter(
song__pk=request.resolver_match.kwargs['object_id'] song__pk=request.resolver_match.kwargs['object_id']
) )
except KeyError:
kwargs['queryset'] = Store.objects.none()
return super().formfield_for_foreignkey(db_field, request, **kwargs) return super().formfield_for_foreignkey(db_field, request, **kwargs)
# Admin Actions
def artist_list(self, obj): def artist_list(self, obj):
return ', '.join([a.full_name for a in obj.artists.all()]) return ', '.join([a.full_name for a in obj.artists.all()])
# Admin Actions
## Metadata CRUD
def add_album(self, request, queryset): def add_album(self, request, queryset):
return change_items(request, queryset, 'album', 'add_album') return change_items(request, queryset, 'album', 'add_album')
add_album.short_description = "Add album to selected items" add_album.short_description = "Add album to selected items"
@ -338,6 +350,28 @@ class SongAdmin(RequestSongActionMixin,
return remove_items(request, queryset, 'game', 'remove_game') return remove_items(request, queryset, 'game', 'remove_game')
remove_game.short_description = "Remove game from selected items" remove_game.short_description = "Remove game from selected items"
## Allow multiple songs to be favorited by the admin user.
def add_favorites(self, request, queryset):
request.user.profile.favorites.add(*queryset)
message = quantify(len(queryset), queryset.model)
messages.success(
request,
'{} successfully added to favorites.'.format(message)
)
add_favorites.short_description = "Add selected songs to favorites"
def remove_favorites(self, request, queryset):
request.user.profile.favorites.remove(*queryset)
message = quantify(len(queryset), queryset.model)
messages.success(
request,
'{} successfully removed from favorites.'.format(message)
)
remove_favorites.short_description = "Remove selected songs from favorites"
## Publish songs if they are sitting unpublished.
def publish_songs(self, request, queryset): def publish_songs(self, request, queryset):
publish_items(request, queryset) publish_items(request, queryset)
publish_songs.short_description = "Publish selected songs" publish_songs.short_description = "Publish selected songs"