Expanded song requests to artists, game, & album.
This commit is contained in:
parent
d9ffd9a3c0
commit
7b3ed3d127
2 changed files with 126 additions and 19 deletions
|
@ -2,7 +2,9 @@ from django.contrib import admin, messages
|
|||
from django.db import models
|
||||
from django.forms import TextInput
|
||||
|
||||
from inline_actions.admin import InlineActionsModelAdminMixin
|
||||
from inline_actions.admin import (
|
||||
InlineActionsMixin, InlineActionsModelAdminMixin
|
||||
)
|
||||
|
||||
from .actions import change_items, publish_items, remove_items
|
||||
from .models import Album, Artist, Game, Song, Store
|
||||
|
@ -10,6 +12,34 @@ from profiles.exceptions import MakeRequestError
|
|||
from profiles.models import RadioProfile
|
||||
|
||||
|
||||
class RequestSongActionMixin(object):
|
||||
'''This allows a song to be requested directly from an admin page.'''
|
||||
def get_inline_actions(self, request, obj=None):
|
||||
actions = super().get_inline_actions(request=request, obj=obj)
|
||||
actions.append('request_song')
|
||||
return actions
|
||||
|
||||
def request_song(self, request, obj, parent_obj=None):
|
||||
profile = RadioProfile.objects.get(user=request.user)
|
||||
|
||||
# This is to get around the M2M 'through' table on Artists
|
||||
song = obj
|
||||
if not isinstance(song, Song):
|
||||
song = obj.song
|
||||
|
||||
try:
|
||||
profile.make_request(song)
|
||||
except MakeRequestError as e:
|
||||
return messages.error(
|
||||
request,
|
||||
'Unable to request the song: {}'.format(str(e))
|
||||
)
|
||||
return messages.success(request, 'Successfully queued song.')
|
||||
|
||||
def get_request_song_label(self, obj):
|
||||
return 'Request Song'
|
||||
|
||||
|
||||
class ArtistInline(admin.TabularInline):
|
||||
model = Song.artists.through
|
||||
verbose_name = 'artist'
|
||||
|
@ -24,12 +54,72 @@ class StoreInline(admin.TabularInline):
|
|||
extra = 0
|
||||
|
||||
|
||||
class SongInline(RequestSongActionMixin,
|
||||
InlineActionsMixin,
|
||||
admin.TabularInline):
|
||||
model = Song
|
||||
readonly_fields = (
|
||||
'title',
|
||||
'game',
|
||||
'album',
|
||||
'artist_list',
|
||||
'_is_enabled',
|
||||
'_is_published',
|
||||
'_is_requestable'
|
||||
)
|
||||
fields = readonly_fields
|
||||
verbose_name = 'related song'
|
||||
verbose_name_plural = 'related songs'
|
||||
extra = 0
|
||||
|
||||
def artist_list(self, obj):
|
||||
return ', '.join([a.full_name for a in obj.artists.all()])
|
||||
|
||||
class SongArtistInline(SongInline):
|
||||
model = Song.artists.through
|
||||
|
||||
# This is VERY hacky and I hate it. I would love to find something
|
||||
# a little more DRY. There's this:
|
||||
# https://gist.github.com/cauethenorio/9db40c59cf406bf328fd
|
||||
# . . .but it seems to be aimed at ModelAdmins, not Inlines. Maybe a
|
||||
# refactor is in order when I understand the underlying functionality
|
||||
# down the road.
|
||||
|
||||
def title(self, obj):
|
||||
return obj.song.title
|
||||
title.short_description = 'title'
|
||||
|
||||
def game(self, obj):
|
||||
return obj.song.game
|
||||
game.short_description = 'game'
|
||||
|
||||
def album(self, obj):
|
||||
return obj.song.album
|
||||
album.short_description = 'album'
|
||||
|
||||
def artist_list(self, obj):
|
||||
return ', '.join([a.full_name for a in obj.song.artists.all()])
|
||||
|
||||
def _is_enabled(self, obj):
|
||||
return obj.song.is_enabled
|
||||
_is_enabled.boolean = True
|
||||
|
||||
def _is_published(self, obj):
|
||||
return obj.song.is_published
|
||||
_is_published.boolean = True
|
||||
|
||||
def _is_requestable(self, obj):
|
||||
return obj.song.is_requestable
|
||||
_is_requestable.boolean = True
|
||||
|
||||
|
||||
@admin.register(Album)
|
||||
class AlbumAdmin(admin.ModelAdmin):
|
||||
class AlbumAdmin(InlineActionsModelAdminMixin, admin.ModelAdmin):
|
||||
# Detail List display
|
||||
list_display = ('title', '_is_enabled', '_is_published')
|
||||
search_fields = ['title']
|
||||
actions = ['publish_albums']
|
||||
inlines = [SongInline]
|
||||
|
||||
# Edit Form display
|
||||
readonly_fields = ('created_date', 'modified_date')
|
||||
|
@ -51,9 +141,14 @@ class AlbumAdmin(admin.ModelAdmin):
|
|||
publish_items(request, queryset)
|
||||
publish_albums.short_description = "Publish selected albums"
|
||||
|
||||
class Media:
|
||||
css = {
|
||||
'all': ('css/remove_inline_object_names.css', )
|
||||
}
|
||||
|
||||
|
||||
@admin.register(Artist)
|
||||
class ArtistAdmin(admin.ModelAdmin):
|
||||
class ArtistAdmin(InlineActionsModelAdminMixin, admin.ModelAdmin):
|
||||
# Detail List display
|
||||
list_display = ('first_name',
|
||||
'alias',
|
||||
|
@ -62,6 +157,7 @@ class ArtistAdmin(admin.ModelAdmin):
|
|||
'_is_published')
|
||||
search_fields = ['first_name', 'alias', 'last_name']
|
||||
actions = ['publish_artists']
|
||||
inlines = [SongArtistInline]
|
||||
|
||||
# Edit Form display
|
||||
readonly_fields = ('created_date', 'modified_date')
|
||||
|
@ -83,13 +179,19 @@ class ArtistAdmin(admin.ModelAdmin):
|
|||
publish_items(request, queryset)
|
||||
publish_artists.short_description = "Publish selected artists"
|
||||
|
||||
class Media:
|
||||
css = {
|
||||
'all': ('css/remove_inline_object_names.css', )
|
||||
}
|
||||
|
||||
|
||||
@admin.register(Game)
|
||||
class GameAdmin(admin.ModelAdmin):
|
||||
class GameAdmin(InlineActionsModelAdminMixin, admin.ModelAdmin):
|
||||
# Detail List display
|
||||
list_display = ('title', '_is_enabled', '_is_published')
|
||||
search_fields = ['title']
|
||||
actions = ['publish_games']
|
||||
inlines = [SongInline]
|
||||
|
||||
# Edit Form display
|
||||
readonly_fields = ('created_date', 'modified_date')
|
||||
|
@ -111,6 +213,11 @@ class GameAdmin(admin.ModelAdmin):
|
|||
publish_items(request, queryset)
|
||||
publish_games.short_description = "Publish selected games"
|
||||
|
||||
class Media:
|
||||
css = {
|
||||
'all': ('css/remove_inline_object_names.css', )
|
||||
}
|
||||
|
||||
|
||||
@admin.register(Store)
|
||||
class StoreAdmin(admin.ModelAdmin):
|
||||
|
@ -141,7 +248,9 @@ class StoreAdmin(admin.ModelAdmin):
|
|||
|
||||
|
||||
@admin.register(Song)
|
||||
class SongAdmin(InlineActionsModelAdminMixin, admin.ModelAdmin):
|
||||
class SongAdmin(RequestSongActionMixin,
|
||||
InlineActionsModelAdminMixin,
|
||||
admin.ModelAdmin):
|
||||
formfield_overrides = {
|
||||
models.TextField: {'widget': TextInput(attrs={'size': 160, })},
|
||||
}
|
||||
|
@ -154,6 +263,7 @@ class SongAdmin(InlineActionsModelAdminMixin, admin.ModelAdmin):
|
|||
'_is_enabled',
|
||||
'_is_published',
|
||||
'_is_requestable')
|
||||
list_select_related = True
|
||||
search_fields = ['title']
|
||||
actions = ['publish_songs',
|
||||
'add_game', 'remove_game',
|
||||
|
@ -194,7 +304,6 @@ class SongAdmin(InlineActionsModelAdminMixin, admin.ModelAdmin):
|
|||
})
|
||||
)
|
||||
inlines = [ArtistInline, StoreInline]
|
||||
inline_actions = ['request_song']
|
||||
|
||||
def formfield_for_foreignkey(self, db_field, request, **kwargs):
|
||||
if db_field.name == 'active_store':
|
||||
|
@ -238,16 +347,7 @@ class SongAdmin(InlineActionsModelAdminMixin, admin.ModelAdmin):
|
|||
publish_items(request, queryset)
|
||||
publish_songs.short_description = "Publish selected songs"
|
||||
|
||||
# Inline Admin Actions
|
||||
|
||||
def request_song(self, request, obj, parent_obj=None):
|
||||
profile = RadioProfile.objects.get(user=request.user)
|
||||
try:
|
||||
profile.make_request(obj)
|
||||
except MakeRequestError as e:
|
||||
return messages.error(
|
||||
request,
|
||||
'Unable to request the song: {}'.format(str(e))
|
||||
)
|
||||
return messages.success(request, 'Successfully queued song.')
|
||||
request_song.short_description = 'Request Song'
|
||||
class Media:
|
||||
css = {
|
||||
'all': ('css/remove_inline_object_names.css', )
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
.inline-group .tabular tr.has_original td {
|
||||
padding-top: 8px;
|
||||
}
|
||||
|
||||
.original {
|
||||
display: none;
|
||||
}
|
Loading…
Reference in a new issue