Django admin inline: Клонировать запись
Я использую GenericStackedInline в моей админке django. Я хотел бы иметь возможность дублировать инлайн объект при редактировании родительского объекта.
Я могу предложить два способа сделать это:
- Использование django-inline-actions для добавления кнопки "clone". Это не сработало, потому что она не отображается при использовании набора полей в GenericStackedInline .
- Добавление еще одного флажка рядом с флажком "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 %}