Moved Song/Artist changes to generic function.
This commit is contained in:
parent
a7ccb61e07
commit
476ddb7a5a
7 changed files with 106 additions and 83 deletions
|
@ -78,14 +78,26 @@ def naturalize(text):
|
||||||
return text
|
return text
|
||||||
|
|
||||||
|
|
||||||
def build_message_start(quantity, model):
|
def quantify(quantity, model):
|
||||||
"""
|
"""
|
||||||
The beggining of a message based on the quantity and singular/plural name
|
A message based on the quantity and singular/plural name of the model.
|
||||||
of the model involved.
|
|
||||||
"""
|
"""
|
||||||
if quantity == 1:
|
if quantity == 1:
|
||||||
message = '1 {} was'.format(model._meta.verbose_name)
|
message = '1 {}'.format(model._meta.verbose_name)
|
||||||
else:
|
else:
|
||||||
message = '{} {} were'.format(str(quantity),
|
message = '{} {}'.format(str(quantity),
|
||||||
model._meta.verbose_name_plural)
|
model._meta.verbose_name_plural)
|
||||||
return message
|
return message
|
||||||
|
|
||||||
|
|
||||||
|
def create_success_message(parent_model, parent_quantity, child_model,
|
||||||
|
child_quantity, remove=False):
|
||||||
|
"""
|
||||||
|
Creates a message for displaying the success of model modification.
|
||||||
|
"""
|
||||||
|
p_message = quantify(parent_quantity, parent_model)
|
||||||
|
c_message = quantify(child_quantity, child_model)
|
||||||
|
if remove:
|
||||||
|
return '{} successfully removed from {}'.format(c_message, p_message)
|
||||||
|
else:
|
||||||
|
return '{} successfully added to {}.'.format(c_message, p_message)
|
||||||
|
|
|
@ -1,10 +1,63 @@
|
||||||
from django.contrib import messages
|
from django.contrib import messages
|
||||||
|
from django.forms import inlineformset_factory
|
||||||
|
from django.http import HttpResponseRedirect
|
||||||
|
from django.shortcuts import render
|
||||||
from django.utils import timezone
|
from django.utils import timezone
|
||||||
|
|
||||||
from core.utils import build_message_start
|
from core.utils import create_success_message, quantify
|
||||||
|
|
||||||
|
|
||||||
|
def change_m2m_items(request, queryset, parent_model, m2m_field,
|
||||||
|
child_field, calling_function, remove=False):
|
||||||
|
through_model = getattr(parent_model, m2m_field)
|
||||||
|
ItemFormSet = inlineformset_factory(parent_model,
|
||||||
|
through_model.through,
|
||||||
|
fields=(child_field,),
|
||||||
|
can_delete=False,
|
||||||
|
extra=10,)
|
||||||
|
# If we clicked Submit, then continue. . .
|
||||||
|
if 'apply' in request.POST:
|
||||||
|
# Fill the formset with values from the POST request
|
||||||
|
item_formset = ItemFormSet(request.POST)
|
||||||
|
|
||||||
|
# Will only returned "cleaned_data" if form is valid, so check
|
||||||
|
if item_formset.is_valid():
|
||||||
|
# Remove the empty form data from the list
|
||||||
|
data = list(filter(None, item_formset.cleaned_data))
|
||||||
|
|
||||||
|
for child in data:
|
||||||
|
for parent in queryset:
|
||||||
|
through = getattr(parent, m2m_field)
|
||||||
|
if request.POST['removal'] == 'True':
|
||||||
|
through.remove(child[child_field])
|
||||||
|
else:
|
||||||
|
through.add(child[child_field])
|
||||||
|
|
||||||
|
# Return with informative success message and counts
|
||||||
|
message = create_success_message(parent_model,
|
||||||
|
queryset.count(),
|
||||||
|
through_model.field.related_model,
|
||||||
|
len(data),
|
||||||
|
request.POST['removal'] == 'True')
|
||||||
|
messages.success(request, message)
|
||||||
|
return HttpResponseRedirect(request.get_full_path())
|
||||||
|
else:
|
||||||
|
messages.error(request, "See below for errors in the form.")
|
||||||
|
# . . .otherwise, create empty formset.
|
||||||
|
else:
|
||||||
|
item_formset = ItemFormSet()
|
||||||
|
|
||||||
|
return render(request,
|
||||||
|
'admin/change_m2m_intermediate.html',
|
||||||
|
{'calling_function': calling_function,
|
||||||
|
'parent_queryset': queryset,
|
||||||
|
'item_formset': item_formset,
|
||||||
|
'parent_model': parent_model,
|
||||||
|
'child_model': through_model.field.related_model,
|
||||||
|
'is_removal': remove, })
|
||||||
|
|
||||||
|
|
||||||
def publish_items(request, queryset):
|
def publish_items(request, queryset):
|
||||||
rows_updated = queryset.update(published_date=timezone.now())
|
rows_updated = queryset.update(published_date=timezone.now())
|
||||||
message = build_message_start(rows_updated, queryset.model)
|
message = quantify(rows_updated, queryset.model)
|
||||||
messages.success(request, '{} successfully published.'.format(message))
|
messages.success(request, '{} successfully published.'.format(message))
|
||||||
|
|
|
@ -1,11 +1,8 @@
|
||||||
from django.contrib import admin, messages
|
from django.contrib import admin
|
||||||
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 .actions import publish_items
|
from .actions import change_m2m_items, publish_items
|
||||||
from .forms import ArtistFormSet
|
|
||||||
from .models import Album, Artist, Game, Song
|
from .models import Album, Artist, Game, Song
|
||||||
|
|
||||||
|
|
||||||
|
@ -158,61 +155,14 @@ 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 change_artists(self, request, queryset, remove=False):
|
|
||||||
artist_formset = None
|
|
||||||
|
|
||||||
# If we clicked Submit, 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, so check
|
|
||||||
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:
|
|
||||||
if request.POST['removal'] == 'True':
|
|
||||||
song.artists.remove(artist['artist'])
|
|
||||||
else:
|
|
||||||
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]
|
|
||||||
if request.POST['removal'] == 'True':
|
|
||||||
act_msg = 'removed from'
|
|
||||||
else:
|
|
||||||
act_msg = 'added to'
|
|
||||||
self.message_user(request,
|
|
||||||
'{} successfully {} {}.'.format(a_msg,
|
|
||||||
act_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/change_artists_intermediate.html',
|
|
||||||
{'songs': queryset,
|
|
||||||
'artist_formset': artist_formset,
|
|
||||||
'is_removal': remove, })
|
|
||||||
|
|
||||||
def add_artists(self, request, queryset):
|
def add_artists(self, request, queryset):
|
||||||
return self.change_artists(request, queryset)
|
return change_m2m_items(request, queryset, Song, 'artists',
|
||||||
|
'artist', 'add_artists')
|
||||||
add_artists.short_description = "Add artists to selected items"
|
add_artists.short_description = "Add artists to selected items"
|
||||||
|
|
||||||
def remove_artists(self, request, queryset):
|
def remove_artists(self, request, queryset):
|
||||||
return self.change_artists(request, queryset, remove=True)
|
return change_m2m_items(request, queryset, Song, 'artists',
|
||||||
|
'artist', 'remove_artists', remove=True)
|
||||||
remove_artists.short_description = "Remove artists from selected items"
|
remove_artists.short_description = "Remove artists from selected items"
|
||||||
|
|
||||||
def publish_songs(self, request, queryset):
|
def publish_songs(self, request, queryset):
|
||||||
|
|
|
@ -1,10 +0,0 @@
|
||||||
from django.forms import inlineformset_factory
|
|
||||||
|
|
||||||
from .models import Song
|
|
||||||
|
|
||||||
|
|
||||||
ArtistFormSet = inlineformset_factory(Song,
|
|
||||||
Song.artists.through,
|
|
||||||
fields=('artist',),
|
|
||||||
can_delete=False,
|
|
||||||
extra=10,)
|
|
|
@ -1,18 +1,19 @@
|
||||||
{% extends "admin/base_site.html" %}
|
{% extends "admin/base_site.html" %}
|
||||||
|
{% load model_names %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<form action="" method="post">
|
<form action="" method="post">
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ artist_formset.management_form }}
|
{{ item_formset.management_form }}
|
||||||
<table>
|
<table>
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th colspan="2">
|
<th colspan="2">
|
||||||
<p>Select up to ten artists to {% if is_removal %}remove from{% else %}add to{% endif %} the songs below:</p>
|
<p>Select up to ten {% model_name_plural child_model %} to {% if is_removal %}remove from{% else %}add to{% endif %} the {% model_name_plural parent_model %} below:</p>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
{% for form in artist_formset %}
|
{% for form in item_formset %}
|
||||||
{{ form }}
|
{{ form }}
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</table>
|
</table>
|
||||||
|
@ -20,25 +21,25 @@
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
<p>Artists will be {% if is_removal %}removed from{% else %}added to{% endif %} the following songs:</p>
|
<p>{% filter capfirst %}{% model_name_plural child_model %}{% endfilter %} will be {% if is_removal %}removed from{% else %}added to{% endif %} the following {% model_name_plural parent_model %}:</p>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for song in songs %}
|
{% for parent in parent_queryset %}
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
{{ song }}
|
{{ parent }}
|
||||||
<input type="hidden" name="_selected_action" value="{{ song.pk }}" />
|
<input type="hidden" name="_selected_action" value="{{ parent.pk }}" />
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<input type="hidden" name="action" value="{% if is_removal %}remove_artists{% else %}add_artists{% endif %}" />
|
<input type="hidden" name="action" value="{{ calling_function }}" />
|
||||||
<input type="hidden" name="removal" value="{{ is_removal }}" />
|
<input type="hidden" name="removal" value="{{ is_removal }}" />
|
||||||
<a href="./"><input type="button" name="Cancel" value="Cancel"></a>
|
<a href="./"><input type="button" name="Cancel" value="Cancel"></a>
|
||||||
<input type="submit" name="apply" value="{% if is_removal %}Remove{% else %}Add{% endif %} Artists" />
|
<input type="submit" name="apply" value="{% if is_removal %}Remove{% else %}Add{% endif %} {% filter capfirst %}{% model_name_plural child_model %}{% endfilter %}" />
|
||||||
</form>
|
</form>
|
||||||
{% endblock %}
|
{% endblock %}
|
0
savepointradio/radio/templatetags/__init__.py
Normal file
0
savepointradio/radio/templatetags/__init__.py
Normal file
17
savepointradio/radio/templatetags/model_names.py
Normal file
17
savepointradio/radio/templatetags/model_names.py
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
from django import template
|
||||||
|
|
||||||
|
|
||||||
|
register = template.Library()
|
||||||
|
|
||||||
|
@register.simple_tag
|
||||||
|
def model_name(value):
|
||||||
|
if hasattr(value, 'model'):
|
||||||
|
value = value.model
|
||||||
|
return value._meta.verbose_name
|
||||||
|
|
||||||
|
|
||||||
|
@register.simple_tag
|
||||||
|
def model_name_plural(value):
|
||||||
|
if hasattr(value, 'model'):
|
||||||
|
value = value.model
|
||||||
|
return value._meta.verbose_name_plural
|
Loading…
Reference in a new issue