BO 1.27 Drag&Drop TrainingPlanDetail, TrainingPlan clone
This commit is contained in:
parent
462877c8a9
commit
2340c3e21a
@ -0,0 +1,8 @@
|
||||
{% extends "adminsortable2/change_list.html" %}
|
||||
|
||||
{% block object-tools-items %}
|
||||
{{ block.super }}
|
||||
<li>
|
||||
<a href="mylink/">My Link</a>
|
||||
</li>
|
||||
{% endblock %}
|
@ -0,0 +1,81 @@
|
||||
{% load i18n admin_urls static admin_modify %}
|
||||
<div class="js-inline-admin-formset inline-group" id="{{ inline_admin_formset.formset.prefix }}-group"
|
||||
data-inline-type="tabular"
|
||||
data-inline-formset="{{ inline_admin_formset.inline_formset_data }}">
|
||||
<div class="tabular inline-related {% if forloop.last %}last-related{% endif %}">
|
||||
{{ inline_admin_formset.formset.management_form }}
|
||||
<fieldset class="module {{ inline_admin_formset.classes }}">
|
||||
{% if inline_admin_formset.formset.max_num == 1 %}
|
||||
<h2>{{ inline_admin_formset.opts.verbose_name|capfirst }}</h2>
|
||||
{% else %}
|
||||
<h2>{{ inline_admin_formset.opts.verbose_name_plural|capfirst }}</h2>
|
||||
{% endif %}
|
||||
{{ inline_admin_formset.formset.non_form_errors }}
|
||||
<table>
|
||||
<thead><tr>
|
||||
<th class="original"></th>
|
||||
{% for field in inline_admin_formset.fields %}
|
||||
{% if not field.widget.is_hidden %}
|
||||
<th class="column-{{ field.name }}{% if field.required %} required{% endif %}">{{ field.label|capfirst }}
|
||||
{% if field.help_text %}<img src="{% static "admin/img/icon-unknown.svg" %}" class="help help-tooltip" width="10" height="10" alt="({{ field.help_text|striptags }})" title="{{ field.help_text|striptags }}">{% endif %}
|
||||
</th>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% if inline_admin_formset.formset.can_delete and inline_admin_formset.has_delete_permission %}<th>{% translate "Delete?" %}</th>{% endif %}
|
||||
<th>{% translate "Clone?" %}</th>
|
||||
</tr></thead>
|
||||
|
||||
<tbody>
|
||||
{% for inline_admin_form in inline_admin_formset %}
|
||||
{% if inline_admin_form.form.non_field_errors %}
|
||||
<tr class="row-form-errors"><td colspan="{{ inline_admin_form|cell_count }}">{{ inline_admin_form.form.non_field_errors }}</td></tr>
|
||||
{% endif %}
|
||||
<tr class="form-row {% if inline_admin_form.original or inline_admin_form.show_url %}has_original{% endif %}{% if forloop.last and inline_admin_formset.has_add_permission %} empty-form{% endif %}"
|
||||
id="{{ inline_admin_formset.formset.prefix }}-{% if not forloop.last %}{{ forloop.counter0 }}{% else %}empty{% endif %}">
|
||||
<td class="original">
|
||||
{% if inline_admin_form.original or inline_admin_form.show_url %}<p>
|
||||
{% if inline_admin_form.original %}
|
||||
{{ inline_admin_form.original }}
|
||||
{% if inline_admin_form.model_admin.show_change_link and inline_admin_form.model_admin.has_registered_model %}<a href="{% url inline_admin_form.model_admin.opts|admin_urlname:'change' inline_admin_form.original.pk|admin_urlquote %}" class="{% if inline_admin_formset.has_change_permission %}inlinechangelink{% else %}inlineviewlink{% endif %}">{% if inline_admin_formset.has_change_permission %}{% translate "Change" %}{% else %}{% translate "View" %}{% endif %}</a>{% endif %}
|
||||
{% endif %}
|
||||
{% if inline_admin_form.show_url %}<a href="{{ inline_admin_form.absolute_url }}">{% translate "View on site" %}</a>{% endif %}
|
||||
</p>{% endif %}
|
||||
{% if inline_admin_form.needs_explicit_pk_field %}{{ inline_admin_form.pk_field.field }}{% endif %}
|
||||
{% if inline_admin_form.fk_field %}{{ inline_admin_form.fk_field.field }}{% endif %}
|
||||
{% spaceless %}
|
||||
{% for fieldset in inline_admin_form %}
|
||||
{% for line in fieldset %}
|
||||
{% for field in line %}
|
||||
{% if not field.is_readonly and field.field.is_hidden %}{{ field.field }}{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endspaceless %}
|
||||
</td>
|
||||
{% for fieldset in inline_admin_form %}
|
||||
{% for line in fieldset %}
|
||||
{% for field in line %}
|
||||
{% if field.is_readonly or not field.field.is_hidden %}
|
||||
<td{% if field.field.name %} class="field-{{ field.field.name }}"{% endif %}>
|
||||
{% if field.is_readonly %}
|
||||
<p>{{ field.contents }}</p>
|
||||
{% else %}
|
||||
{{ field.field.errors.as_ul }}
|
||||
{{ field.field }}
|
||||
{% endif %}
|
||||
</td>
|
||||
{% endif %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% endfor %}
|
||||
{% if inline_admin_formset.formset.can_delete and inline_admin_formset.has_delete_permission %}
|
||||
<td class="delete">{% if inline_admin_form.original %}{{ inline_admin_form.deletion_field.field }}{% endif %}</td>
|
||||
{% endif %}
|
||||
<td class="clone">{{ inline_admin_form.clone_field.field }}</td>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
</table>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
@ -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 = '<span style="color: #{};font-size:32px">{}</span>'.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()
|
||||
|
@ -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):
|
||||
|
@ -49,6 +49,8 @@ INSTALLED_APPS = [
|
||||
'ckeditor_uploader',
|
||||
'django_admin_json_editor',
|
||||
'rangefilter',
|
||||
'adminsortable2',
|
||||
'inline_actions',
|
||||
#'django_cron',
|
||||
]
|
||||
|
||||
|
@ -45,6 +45,8 @@ INSTALLED_APPS = [
|
||||
'ckeditor_uploader',
|
||||
'django_admin_json_editor',
|
||||
'rangefilter',
|
||||
'adminsortable2',
|
||||
'inline_actions',
|
||||
#'django_cron',
|
||||
]
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user