From 2340c3e21a226e2d1f209c2120d177fd45bd8bff Mon Sep 17 00:00:00 2001 From: "Tibor Bossanyi (Freelancer)" Date: Thu, 9 Sep 2021 20:20:25 +0200 Subject: [PATCH] BO 1.27 Drag&Drop TrainingPlanDetail, TrainingPlan clone --- .../admin/change_list.html | 8 ++ .../admin/edit_inline/tabular.html | 81 +++++++++++++++++++ .../admin/training_plan.py | 62 ++++++++++---- .../models/training_plan.py | 1 + .../aitrainer_backoffice/settings/dev.py | 2 + .../aitrainer_backoffice/settings/prod.py | 2 + 6 files changed, 141 insertions(+), 15 deletions(-) create mode 100644 aitrainer_backoffice/aitrainer_backoffice/admin/change_list.html create mode 100644 aitrainer_backoffice/aitrainer_backoffice/admin/edit_inline/tabular.html diff --git a/aitrainer_backoffice/aitrainer_backoffice/admin/change_list.html b/aitrainer_backoffice/aitrainer_backoffice/admin/change_list.html new file mode 100644 index 0000000..98a1e28 --- /dev/null +++ b/aitrainer_backoffice/aitrainer_backoffice/admin/change_list.html @@ -0,0 +1,8 @@ +{% extends "adminsortable2/change_list.html" %} + +{% block object-tools-items %} + {{ block.super }} +
  • + My Link +
  • +{% endblock %} \ No newline at end of file diff --git a/aitrainer_backoffice/aitrainer_backoffice/admin/edit_inline/tabular.html b/aitrainer_backoffice/aitrainer_backoffice/admin/edit_inline/tabular.html new file mode 100644 index 0000000..f81d25f --- /dev/null +++ b/aitrainer_backoffice/aitrainer_backoffice/admin/edit_inline/tabular.html @@ -0,0 +1,81 @@ +{% load i18n admin_urls static admin_modify %} +
    + +
    diff --git a/aitrainer_backoffice/aitrainer_backoffice/admin/training_plan.py b/aitrainer_backoffice/aitrainer_backoffice/admin/training_plan.py index 2730b22..121a497 100644 --- a/aitrainer_backoffice/aitrainer_backoffice/admin/training_plan.py +++ b/aitrainer_backoffice/aitrainer_backoffice/admin/training_plan.py @@ -1,20 +1,22 @@ +from adminsortable2.admin import SortableAdminMixin, SortableInlineAdminMixin from django.contrib import admin from django.utils.html import format_html from django.utils.translation import ugettext_lazy as _ +from inline_actions.admin import InlineActionsMixin +from inline_actions.admin import InlineActionsModelAdminMixin from ..models.training_plan import TrainingPlan, TrainingPlanDetail, TrainingPlanTranslation -class TrainingPlanDetailInline(admin.TabularInline): +class TrainingPlanDetailInline(InlineActionsMixin, SortableInlineAdminMixin, admin.TabularInline): model = TrainingPlanDetail - #fk_name = 'training_plan_detail_id' extra = 0 list_display = ( - 'training_plan', 'exercise_type', 'sort', 'set', 'repeats', 'max', 'weight', 'calc', + 'sort', 'training_plan', 'exercise_type', 'set', 'repeats', 'max', 'weight', 'calc', 'resting_time', 'parallel', 'day') - list_filter = ('training_plan__name', 'exercise_type__name') list_editable = ( - 'exercise_type', 'sort', 'set', 'repeats', 'weight', 'resting_time', 'parallel', 'day') + 'sort', 'exercise_type', 'set', 'repeats', 'weight', 'resting_time', 'parallel', 'day') + list_display_links = ('sort', ) ordering = ('sort',) def repeat_max(self, obj): @@ -39,12 +41,17 @@ class TrainingPlanDetailInline(admin.TabularInline): pass return response - def copy_attributes(self, request, queryset): - name = str(queryset[0].training_plan) + def get_inline_actions(self, request, obj=None): + actions = super(TrainingPlanDetailInline, self).get_inline_actions(request, obj) + return actions + + def copy_attributes(self, request, obj, parent_obj=None): + + name = str(request.queryset[0].training_plan) details = TrainingPlanDetail.objects.filter(training_plan__name=name).order_by('sort') new_sort = details[len(details) - 1].sort + 1 - for objectAttr in queryset: + for objectAttr in request.queryset: objectAttr.pk = None objectAttr.sort = new_sort objectAttr.save() @@ -82,8 +89,6 @@ class TrainingPlanDetailInline(admin.TabularInline): html = '{}'.format(color_code, "*") return format_html(html) - actions = [copy_attributes, select_max_repeat, select_weight_calc] - class TranslationTrainingPlanInline(admin.TabularInline): model = TrainingPlanTranslation @@ -91,7 +96,7 @@ class TranslationTrainingPlanInline(admin.TabularInline): extra = 0 -class TrainingPlanAdmin(admin.ModelAdmin): +class TrainingPlanAdmin(InlineActionsModelAdminMixin, admin.ModelAdmin): list_display = ('training_plan_id', 'name', 'internal_name', 'free', 'active') fields = ('tree', 'name', 'description', 'internal_name', 'free', 'active') list_editable = ('name', 'internal_name', 'free', 'active') @@ -101,14 +106,41 @@ class TrainingPlanAdmin(admin.ModelAdmin): TrainingPlanDetailInline ] + @admin.action(description='clone selected training plans') + def clone(self, request, queryset): + for trainingPlan in queryset: + print("clone " + trainingPlan.name) + id = trainingPlan.training_plan_id + trainingPlan.pk = None + trainingPlan.name = trainingPlan.name + " COPY" + trainingPlan.internal_name = trainingPlan.internal_name + "_copy" + trainingPlan.active = False + trainingPlan.save() + newId = trainingPlan.pk -class TrainingPlanDetailAdmin(admin.ModelAdmin): + details = TrainingPlanDetail.objects.filter(training_plan__training_plan_id=id) + for detail in details: + detail.pk = None + detail.training_plan_id = newId + detail.save() + + translations = TrainingPlanTranslation.objects.filter(training_plan__training_plan_id=id) + for translation in translations: + translation.pk = None + translation.training_plan_id = newId + translation.name_translation = translation.name_translation + " COPY" + translation.save() + + actions = ['clone'] + + +class TrainingPlanDetailAdmin(SortableAdminMixin, admin.ModelAdmin): list_display = ( - 'training_plan', 'exercise_type', 'sort', 'set', 'repeats', 'max', 'weight', 'calc', + 'sort', 'training_plan', 'exercise_type', 'set', 'repeats', 'max', 'weight', 'calc', 'resting_time', 'parallel', 'day') list_filter = ('training_plan__name', 'exercise_type__name') list_editable = ( - 'exercise_type', 'sort', 'set', 'repeats', 'weight', 'resting_time', 'parallel', 'day') + 'exercise_type', 'set', 'repeats', 'weight', 'resting_time', 'parallel', 'day') ordering = ('sort',) def repeat_max(self, obj): @@ -180,5 +212,5 @@ class TrainingPlanDetailAdmin(admin.ModelAdmin): admin.site.register(TrainingPlan, TrainingPlanAdmin) -#admin.site.register(TrainingPlanDetail, TrainingPlanDetailAdmin) +admin.site.register(TrainingPlanDetail, TrainingPlanDetailAdmin) admin.autodiscover() diff --git a/aitrainer_backoffice/aitrainer_backoffice/models/training_plan.py b/aitrainer_backoffice/aitrainer_backoffice/models/training_plan.py index fd5ac39..75fe81f 100644 --- a/aitrainer_backoffice/aitrainer_backoffice/models/training_plan.py +++ b/aitrainer_backoffice/aitrainer_backoffice/models/training_plan.py @@ -43,6 +43,7 @@ class TrainingPlanDetail(models.Model): db_table = 'training_plan_detail' verbose_name = _("Training Plan Detail") verbose_name_plural = _("Training Plan Details") + ordering = ['sort'] class TrainingPlanTranslation(models.Model): diff --git a/aitrainer_backoffice/aitrainer_backoffice/settings/dev.py b/aitrainer_backoffice/aitrainer_backoffice/settings/dev.py index f7d9186..c5e4572 100644 --- a/aitrainer_backoffice/aitrainer_backoffice/settings/dev.py +++ b/aitrainer_backoffice/aitrainer_backoffice/settings/dev.py @@ -49,6 +49,8 @@ INSTALLED_APPS = [ 'ckeditor_uploader', 'django_admin_json_editor', 'rangefilter', + 'adminsortable2', + 'inline_actions', #'django_cron', ] diff --git a/aitrainer_backoffice/aitrainer_backoffice/settings/prod.py b/aitrainer_backoffice/aitrainer_backoffice/settings/prod.py index cec4200..cc8ac59 100644 --- a/aitrainer_backoffice/aitrainer_backoffice/settings/prod.py +++ b/aitrainer_backoffice/aitrainer_backoffice/settings/prod.py @@ -45,6 +45,8 @@ INSTALLED_APPS = [ 'ckeditor_uploader', 'django_admin_json_editor', 'rangefilter', + 'adminsortable2', + 'inline_actions', #'django_cron', ]