Add admin actions for adding/removing multiple artists to songs.
This commit is contained in:
parent
d8379fe198
commit
65fb7d9f15
4 changed files with 182 additions and 10 deletions
|
@ -1,8 +1,11 @@
|
||||||
from django.contrib import admin
|
from django.contrib import admin, messages
|
||||||
from django.db import models
|
from django.db import models
|
||||||
from django.forms import TextInput
|
from django.forms import TextInput
|
||||||
|
from django.http import HttpResponseRedirect
|
||||||
|
from django.shortcuts import render
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
|
from .forms import ArtistFormSet
|
||||||
from .models import Album, Artist, Game, Song
|
from .models import Album, Artist, Game, Song
|
||||||
|
|
||||||
|
|
||||||
|
@ -15,8 +18,6 @@ class ArtistInline(admin.TabularInline):
|
||||||
|
|
||||||
@admin.register(Album)
|
@admin.register(Album)
|
||||||
class AlbumAdmin(admin.ModelAdmin):
|
class AlbumAdmin(admin.ModelAdmin):
|
||||||
ordering = ("sorted_title",)
|
|
||||||
|
|
||||||
# Detail List display
|
# Detail List display
|
||||||
list_display = ('title', '_is_enabled', '_is_published')
|
list_display = ('title', '_is_enabled', '_is_published')
|
||||||
search_fields = ['title']
|
search_fields = ['title']
|
||||||
|
@ -50,8 +51,6 @@ class AlbumAdmin(admin.ModelAdmin):
|
||||||
|
|
||||||
@admin.register(Artist)
|
@admin.register(Artist)
|
||||||
class ArtistAdmin(admin.ModelAdmin):
|
class ArtistAdmin(admin.ModelAdmin):
|
||||||
ordering = ("sorted_full_name",)
|
|
||||||
|
|
||||||
# Detail List display
|
# Detail List display
|
||||||
list_display = ('first_name',
|
list_display = ('first_name',
|
||||||
'alias',
|
'alias',
|
||||||
|
@ -89,8 +88,6 @@ class ArtistAdmin(admin.ModelAdmin):
|
||||||
|
|
||||||
@admin.register(Game)
|
@admin.register(Game)
|
||||||
class GameAdmin(admin.ModelAdmin):
|
class GameAdmin(admin.ModelAdmin):
|
||||||
ordering = ("sorted_title",)
|
|
||||||
|
|
||||||
# Detail List display
|
# Detail List display
|
||||||
list_display = ('title', '_is_enabled', '_is_published')
|
list_display = ('title', '_is_enabled', '_is_published')
|
||||||
search_fields = ['title']
|
search_fields = ['title']
|
||||||
|
@ -124,8 +121,6 @@ class GameAdmin(admin.ModelAdmin):
|
||||||
|
|
||||||
@admin.register(Song)
|
@admin.register(Song)
|
||||||
class SongAdmin(admin.ModelAdmin):
|
class SongAdmin(admin.ModelAdmin):
|
||||||
ordering = ("sorted_title",)
|
|
||||||
|
|
||||||
formfield_overrides = {
|
formfield_overrides = {
|
||||||
models.TextField: {'widget': TextInput(attrs={'size': 160, })},
|
models.TextField: {'widget': TextInput(attrs={'size': 160, })},
|
||||||
}
|
}
|
||||||
|
@ -133,11 +128,12 @@ class SongAdmin(admin.ModelAdmin):
|
||||||
# Detail List display
|
# Detail List display
|
||||||
list_display = ('title',
|
list_display = ('title',
|
||||||
'game',
|
'game',
|
||||||
|
'album',
|
||||||
'artist_list',
|
'artist_list',
|
||||||
'_is_enabled',
|
'_is_enabled',
|
||||||
'_is_published')
|
'_is_published')
|
||||||
search_fields = ['title']
|
search_fields = ['title']
|
||||||
actions = ['publish_items']
|
actions = ['publish_items', 'add_artists', 'remove_artists']
|
||||||
|
|
||||||
# Edit Form display
|
# Edit Form display
|
||||||
exclude = ('artists',)
|
exclude = ('artists',)
|
||||||
|
@ -177,6 +173,86 @@ class SongAdmin(admin.ModelAdmin):
|
||||||
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()])
|
||||||
|
|
||||||
|
def add_artists(self, request, queryset):
|
||||||
|
artist_formset = None
|
||||||
|
|
||||||
|
# If we clicked "Add Artists", then continue. . .
|
||||||
|
if 'apply' in request.POST:
|
||||||
|
# Fill the formset with values from the POST request
|
||||||
|
artist_formset = ArtistFormSet(request.POST)
|
||||||
|
|
||||||
|
# Will only returned "cleaned_data" if form is valid
|
||||||
|
if artist_formset.is_valid():
|
||||||
|
# remove the empty form data from the list
|
||||||
|
data = list(filter(None, artist_formset.cleaned_data))
|
||||||
|
|
||||||
|
for artist in data:
|
||||||
|
for song in queryset:
|
||||||
|
song.artists.add(artist['artist'])
|
||||||
|
|
||||||
|
# Return with informative success message and counts
|
||||||
|
a_count = len(data)
|
||||||
|
s_count = queryset.count()
|
||||||
|
a_msg = ('1 artist was',
|
||||||
|
'{} artists were'.format(a_count))[a_count > 1]
|
||||||
|
s_msg = ('1 song', '{} songs'.format(s_count))[s_count > 1]
|
||||||
|
self.message_user(request,
|
||||||
|
'{} successfully added to {}.'.format(a_msg,
|
||||||
|
s_msg))
|
||||||
|
return HttpResponseRedirect(request.get_full_path())
|
||||||
|
else:
|
||||||
|
self.message_user(request,
|
||||||
|
"See below for errors in the form.",
|
||||||
|
level=messages.ERROR)
|
||||||
|
# . . .otherwise, create empty formset.
|
||||||
|
if not artist_formset:
|
||||||
|
artist_formset = ArtistFormSet()
|
||||||
|
|
||||||
|
return render(request,
|
||||||
|
'admin/add_artists_intermediate.html',
|
||||||
|
{'songs': queryset, 'artist_formset': artist_formset, })
|
||||||
|
add_artists.short_description = "Add artists to selected items"
|
||||||
|
|
||||||
|
def remove_artists(self, request, queryset):
|
||||||
|
artist_formset = None
|
||||||
|
|
||||||
|
# If we clicked "Remove Artists", then continue. . .
|
||||||
|
if 'apply' in request.POST:
|
||||||
|
# Fill the formset with values from the POST request
|
||||||
|
artist_formset = ArtistFormSet(request.POST)
|
||||||
|
|
||||||
|
# Will only returned "cleaned_data" if form is valid
|
||||||
|
if artist_formset.is_valid():
|
||||||
|
# remove the empty form data from the list
|
||||||
|
data = list(filter(None, artist_formset.cleaned_data))
|
||||||
|
|
||||||
|
for artist in data:
|
||||||
|
for song in queryset:
|
||||||
|
song.artists.remove(artist['artist'])
|
||||||
|
|
||||||
|
# Return with informative success message and counts
|
||||||
|
a_count = len(data)
|
||||||
|
s_count = queryset.count()
|
||||||
|
a_msg = ('1 artist was',
|
||||||
|
'{} artists were'.format(a_count))[a_count > 1]
|
||||||
|
s_msg = ('1 song', '{} songs'.format(s_count))[s_count > 1]
|
||||||
|
self.message_user(request,
|
||||||
|
'{} successfully removed from {}.'.format(a_msg,
|
||||||
|
s_msg))
|
||||||
|
return HttpResponseRedirect(request.get_full_path())
|
||||||
|
else:
|
||||||
|
self.message_user(request,
|
||||||
|
"See below for errors in the form.",
|
||||||
|
level=messages.ERROR)
|
||||||
|
# . . .otherwise, create empty formset.
|
||||||
|
if not artist_formset:
|
||||||
|
artist_formset = ArtistFormSet()
|
||||||
|
|
||||||
|
return render(request,
|
||||||
|
'admin/remove_artists_intermediate.html',
|
||||||
|
{'songs': queryset, 'artist_formset': artist_formset, })
|
||||||
|
remove_artists.short_description = "Remove artists from selected items"
|
||||||
|
|
||||||
def publish_items(self, request, queryset):
|
def publish_items(self, request, queryset):
|
||||||
rows_updated = queryset.update(published_date=timezone.now())
|
rows_updated = queryset.update(published_date=timezone.now())
|
||||||
if rows_updated == 1:
|
if rows_updated == 1:
|
||||||
|
|
10
savepointradio/radio/forms.py
Normal file
10
savepointradio/radio/forms.py
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
from django.forms import inlineformset_factory
|
||||||
|
|
||||||
|
from .models import Song
|
||||||
|
|
||||||
|
|
||||||
|
ArtistFormSet = inlineformset_factory(Song,
|
||||||
|
Song.artists.through,
|
||||||
|
fields=('artist',),
|
||||||
|
can_delete=False,
|
||||||
|
extra=10,)
|
|
@ -0,0 +1,43 @@
|
||||||
|
{% extends "admin/base_site.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<form action="" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ artist_formset.management_form }}
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th colspan="2">
|
||||||
|
<p>Select up to ten artists to add to the songs below:</p>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
{% for form in artist_formset %}
|
||||||
|
{{ form }}
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<p>Artists will be added to the following songs:</p>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for song in songs %}
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
{{ song }}
|
||||||
|
<input type="hidden" name="_selected_action" value="{{ song.pk }}" />
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<input type="hidden" name="action" value="add_artists" />
|
||||||
|
<a href="./"><input type="button" name="Cancel" value="Cancel"></a>
|
||||||
|
<input type="submit" name="apply" value="Add Artists" />
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
|
@ -0,0 +1,43 @@
|
||||||
|
{% extends "admin/base_site.html" %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<form action="" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
{{ artist_formset.management_form }}
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th colspan="2">
|
||||||
|
<p>Select up to ten artists to remove from the songs below:</p>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
{% for form in artist_formset %}
|
||||||
|
{{ form }}
|
||||||
|
{% endfor %}
|
||||||
|
</table>
|
||||||
|
<table>
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
<p>Artists will be removed from the following songs:</p>
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
{% for song in songs %}
|
||||||
|
<tr>
|
||||||
|
<th>
|
||||||
|
{{ song }}
|
||||||
|
<input type="hidden" name="_selected_action" value="{{ song.pk }}" />
|
||||||
|
</th>
|
||||||
|
</tr>
|
||||||
|
{% endfor %}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<input type="hidden" name="action" value="remove_artists" />
|
||||||
|
<a href="./"><input type="button" name="Cancel" value="Cancel"></a>
|
||||||
|
<input type="submit" name="apply" value="Remove Artists" />
|
||||||
|
</form>
|
||||||
|
{% endblock %}
|
Loading…
Reference in a new issue