From 00e56dd09604fbd680fe911cf6893d1cfd544de8 Mon Sep 17 00:00:00 2001 From: Erik Stein Date: Mon, 24 Dec 2018 10:39:56 +0100 Subject: [PATCH] AdminActionBase. --- CHANGES | 2 + shared/utils/admin_actions.py | 75 +++++++++++++++++++ .../admin/action_forms/admin_action_base.html | 30 ++++++++ 3 files changed, 107 insertions(+) create mode 100644 shared/utils/admin_actions.py create mode 100644 shared/utils/templates/admin/action_forms/admin_action_base.html diff --git a/CHANGES b/CHANGES index 4a46d3d..1b6011d 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,6 @@ - Added dispatch_slug_path. +- Added AdminActionBase. + 0.2.17 2018-12-17 - PageTitlesMixin: Slimdown name for get_short_title. - Daytime utils. diff --git a/shared/utils/admin_actions.py b/shared/utils/admin_actions.py new file mode 100644 index 0000000..54b4f52 --- /dev/null +++ b/shared/utils/admin_actions.py @@ -0,0 +1,75 @@ + +from django import forms +from django.contrib import admin +from django.http import HttpResponseRedirect +from django.shortcuts import render + + +class AdminActionBase: + action_name = None + options_template_name = 'admin/action_forms/admin_action_base.html' + title = None + queryset_action_label = None + action_button_label = None + + def apply(self, queryset, form): + raise NotImplementedError + + def get_message(self, count): + raise NotImplementedError + + def get_failure_message(self, count, failure_count): + raise NotImplementedError + + class BaseForm(forms.Form): + _selected_action = forms.CharField(widget=forms.MultipleHiddenInput) + + def get_form_class(self, modeladmin, request, queryset): + """ + Example: + + class CustomForm(BaseForm) + chosen_target = forms.ModelChoiceField( + label=_("Choose target itembundle"), + queryset=ItemBundle.objects.exclude(pk__in=queryset), + widget=ForeignKeyRawIdWidget(modeladmin.model._meta.get_field('parent').rel, modeladmin.admin_site), + empty_label=_("Root level"), required=False) + return CustomForm + """ + raise NotImplementedError + + def __call__(self, modeladmin, request, queryset): + form_class = self.get_form_class(modeladmin, request, queryset) + + form = None + if 'apply' in request.POST: + form = form_class(request.POST) + if form.is_valid(): + queryset_count = queryset.count() + count = self.apply(queryset, form) + failure_count = queryset_count - count + if failure_count > 0: + message = self.get_failure_message(form, count, failure_count) + else: + message = self.get_message(form, count) + modeladmin.message_user(request, message) + return HttpResponseRedirect(request.get_full_path()) + + if 'cancel' in request.POST: + return HttpResponseRedirect(request.get_full_path()) + + if not form: + form = form_class(initial={ + '_selected_action': request.POST.getlist( + admin.ACTION_CHECKBOX_NAME), + }) + + return render(request, self.options_template_name, context={ + 'action_name': self.action_name, + 'title': self.title, + 'queryset_action_label': self.queryset_action_label, + 'action_button_label': self.action_button_label, + 'queryset': queryset, + 'action_form': form, + 'opts': modeladmin.model._meta, + }) diff --git a/shared/utils/templates/admin/action_forms/admin_action_base.html b/shared/utils/templates/admin/action_forms/admin_action_base.html new file mode 100644 index 0000000..cf2dd59 --- /dev/null +++ b/shared/utils/templates/admin/action_forms/admin_action_base.html @@ -0,0 +1,30 @@ +{% extends "admin/change_form.html" %}{# Needed for admin javascripts #} +{% load i18n static %} + + +{% block title %}{{ title }}{% endblock %} + + +{% block content %} +
+
{% csrf_token %} +
+ {{ action_form.as_p }} + {% for obj in queryset %} + + {% endfor %} + +

{{ queryset_action_label }}

+ +
    + {{ queryset|unordered_list }} +
+ + + + + {# {% trans "No, take me back" %} #} +
+
+
+{% endblock %}