From 476ddb7a5a890575065900e3e45014897a15bad8 Mon Sep 17 00:00:00 2001 From: RecursiveGreen Date: Sun, 14 Jan 2018 18:38:14 -0500 Subject: [PATCH] Moved Song/Artist changes to generic function. --- savepointradio/core/utils.py | 24 +++++-- savepointradio/radio/actions.py | 57 ++++++++++++++++- savepointradio/radio/admin.py | 62 ++----------------- savepointradio/radio/forms.py | 10 --- ...iate.html => change_m2m_intermediate.html} | 19 +++--- savepointradio/radio/templatetags/__init__.py | 0 .../radio/templatetags/model_names.py | 17 +++++ 7 files changed, 106 insertions(+), 83 deletions(-) delete mode 100644 savepointradio/radio/forms.py rename savepointradio/radio/templates/admin/{change_artists_intermediate.html => change_m2m_intermediate.html} (51%) create mode 100644 savepointradio/radio/templatetags/__init__.py create mode 100644 savepointradio/radio/templatetags/model_names.py diff --git a/savepointradio/core/utils.py b/savepointradio/core/utils.py index 6cc219a..a0d0a9d 100644 --- a/savepointradio/core/utils.py +++ b/savepointradio/core/utils.py @@ -78,14 +78,26 @@ def naturalize(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 - of the model involved. + A message based on the quantity and singular/plural name of the model. """ if quantity == 1: - message = '1 {} was'.format(model._meta.verbose_name) + message = '1 {}'.format(model._meta.verbose_name) else: - message = '{} {} were'.format(str(quantity), - model._meta.verbose_name_plural) + message = '{} {}'.format(str(quantity), + model._meta.verbose_name_plural) 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) diff --git a/savepointradio/radio/actions.py b/savepointradio/radio/actions.py index 4bf0f51..2f8edbc 100644 --- a/savepointradio/radio/actions.py +++ b/savepointradio/radio/actions.py @@ -1,10 +1,63 @@ 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 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): 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)) diff --git a/savepointradio/radio/admin.py b/savepointradio/radio/admin.py index cad7373..5908cb1 100644 --- a/savepointradio/radio/admin.py +++ b/savepointradio/radio/admin.py @@ -1,11 +1,8 @@ -from django.contrib import admin, messages +from django.contrib import admin from django.db import models from django.forms import TextInput -from django.http import HttpResponseRedirect -from django.shortcuts import render -from .actions import publish_items -from .forms import ArtistFormSet +from .actions import change_m2m_items, publish_items from .models import Album, Artist, Game, Song @@ -158,61 +155,14 @@ class SongAdmin(admin.ModelAdmin): def artist_list(self, obj): 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): - 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" 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" def publish_songs(self, request, queryset): diff --git a/savepointradio/radio/forms.py b/savepointradio/radio/forms.py deleted file mode 100644 index 065b690..0000000 --- a/savepointradio/radio/forms.py +++ /dev/null @@ -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,) diff --git a/savepointradio/radio/templates/admin/change_artists_intermediate.html b/savepointradio/radio/templates/admin/change_m2m_intermediate.html similarity index 51% rename from savepointradio/radio/templates/admin/change_artists_intermediate.html rename to savepointradio/radio/templates/admin/change_m2m_intermediate.html index d08977a..e693efc 100644 --- a/savepointradio/radio/templates/admin/change_artists_intermediate.html +++ b/savepointradio/radio/templates/admin/change_m2m_intermediate.html @@ -1,18 +1,19 @@ {% extends "admin/base_site.html" %} +{% load model_names %} {% block content %}
{% csrf_token %} - {{ artist_formset.management_form }} + {{ item_formset.management_form }} - {% for form in artist_formset %} + {% for form in item_formset %} {{ form }} {% endfor %}
-

Select up to ten artists to {% if is_removal %}remove from{% else %}add to{% endif %} the songs below:

+

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:

@@ -20,25 +21,25 @@ -

Artists will be {% if is_removal %}removed from{% else %}added to{% endif %} the following songs:

+

{% 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 %}:

- {% for song in songs %} + {% for parent in parent_queryset %} - {{ song }} - + {{ parent }} + {% endfor %} - + - +
{% endblock %} \ No newline at end of file diff --git a/savepointradio/radio/templatetags/__init__.py b/savepointradio/radio/templatetags/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/savepointradio/radio/templatetags/model_names.py b/savepointradio/radio/templatetags/model_names.py new file mode 100644 index 0000000..521960e --- /dev/null +++ b/savepointradio/radio/templatetags/model_names.py @@ -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