Django admin inline: Клонировать запись

Я использую GenericStackedInline в моей админке django. Я хотел бы иметь возможность дублировать инлайн объект при редактировании родительского объекта.

Я могу предложить два способа сделать это:

  1. Использование django-inline-actions для добавления кнопки "clone". Это не сработало, потому что она не отображается при использовании набора полей в GenericStackedInline
  2. .
  3. Добавление еще одного флажка рядом с флажком "delete" с меткой "clone". При активации флажка и сохранении родительского объекта, он должен клонировать инлайн объект с новым id. Есть ли простой способ добавить еще один флажок и добавить действие для обработки клонирования?

Ок, нашел решение. Мне оно не очень нравится. Самый большой недостаток, на мой взгляд, в том, что я не нашел способа сделать клон в InlineClass, Mixin или наборе форм. Это немного неуклюже, что два класса / Mixins должны быть объединены, чтобы справиться с этим.

Усовершенствования или другие решения очень приветствуются.

Inline classes

class RgCloneInlineFormset(BaseGenericInlineFormSet):
    def add_fields(self, form, index):
        super().add_fields(form, index)
        form.fields["CLONE"] = forms.BooleanField(required=False)

class RgGenericStackedInlineWithClone(GenericStackedInline):
    template = "admin/edit_inline/stacked_with_clone.html"
    formset = RgCloneInlineFormset

class DetailpageElementInline(RgGenericStackedInlineWithClone, RgImagePreviewMixin):
    model = DetailpageElement
    extra = 0

Класс администратора

class CloneDetailpageElementInlineMixin():

    def save_formset(self, request, form, formset, change):
        # Save formset
        ret = super().save_formset(request, form, formset, change)

        # Do clone if nessesary
        detailpage_ids_to_clone = []

        for data in formset.cleaned_data:
            if isinstance(data.get("id"), DetailpageElement):
                if data.get("CLONE"):
                    detailpage_ids_to_clone.append(data.get("id").id)

        for detailpage_element in DetailpageElement.objects.filter(id__in=detailpage_ids_to_clone):
            detailpage_element.id = None
            detailpage_element.save()
        
        # Make sure function works like super function
        return ret

@admin.register(ArticleInt)
class ArticleIntAdmin(CloneDetailpageElementInlineMixin, ContentAdminBase):
    inlines = [
        inlines.DetailpageElementInline,
    ] 

Шаблон admin/edit_inline/stacked_with_clone.html. Просто скопировал stacked.html из исходного кода django и добавил {% if inline_admin_formset.has_add_permission and inline_admin_form.original %}<span class="clone">{{ inline_admin_form.form.CLONE }} Clone</span>{% endif %}

Вернуться на верх