Django Admin中GenericStackedInline对象复制功能实现问询
Django Admin GenericStackedInline 关联对象复制实现方案
方案一:修复django-inline-actions在带fieldset的GenericStackedInline中显示按钮的问题
django-inline-actions默认模板不会把按钮渲染到fieldset区域内,只需自定义inline模板即可解决:
- 定义继承
InlineActionsMixin的GenericStackedInline类,实现克隆逻辑:
from django.contrib.contenttypes.admin import GenericStackedInline from inline_actions.admin import InlineActionsMixin class YourGenericInline(InlineActionsMixin, GenericStackedInline): model = YourRelatedModel fieldsets = ( ('基本信息', { 'fields': ('name', 'content',) }), ) inline_actions = ['clone_object'] def clone_object(self, request, obj, parent_obj): # 复制对象并关联到当前父对象 cloned_obj = obj.__class__.objects.get(pk=obj.pk) cloned_obj.pk = None cloned_obj.content_object = parent_obj cloned_obj.save()
- 自定义inline模板
admin/your_app/your_generic_inline.html,将action按钮插入到fieldset之后:
{% extends "admin/edit_inline/stacked.html" %} {% load inline_actions %} {% block inline_fieldset %} {{ block.super }} {% inline_actions for inline form %} {% endblock %}
- 在Inline类中指定自定义模板:
class YourGenericInline(InlineActionsMixin, GenericStackedInline): # ... 其他配置 template = 'admin/your_app/your_generic_inline.html'
方案二:添加“Clone”复选框,保存时自动复制对象
无需额外依赖,通过自定义表单和重写父模型Admin的save_formset实现:
- 自定义inline表单,添加克隆复选框:
from django import forms class YourInlineForm(forms.ModelForm): clone = forms.BooleanField(label='Clone', required=False) class Meta: model = YourRelatedModel fields = '__all__'
- 在GenericStackedInline中使用该表单:
class YourGenericInline(GenericStackedInline): model = YourRelatedModel form = YourInlineForm fieldsets = ( ('基本信息', { 'fields': ('name', 'content',) }), )
- 重写父模型Admin的
save_formset方法,处理克隆逻辑:
from django.contrib import admin from .models import ParentModel, YourRelatedModel @admin.register(ParentModel) class ParentModelAdmin(admin.ModelAdmin): inlines = [YourGenericInline] def save_formset(self, request, form, formset, change): instances = formset.save(commit=False) formset.save_m2m() # 删除标记删除的对象 for obj in formset.deleted_objects: obj.delete() # 处理克隆请求 for instance in instances: if getattr(instance, 'clone', False): clone_obj = instance.__class__.objects.get(pk=instance.pk) clone_obj.pk = None clone_obj.content_object = form.instance clone_obj.save() instance.save()
内容的提问来源于stack exchange,提问作者user1383029
相关产品推荐
相关产品推荐

