如何在Django Admin修改页删除所有内联对象时保留第一个
解决方案
要实现删除所有内联Email对象时保留第一个,你可以通过自定义内联表单集来控制删除逻辑,具体步骤如下:
1. 自定义表单集,添加验证逻辑
在admin.py中定义继承自BaseInlineFormSet的表单集,重写clean方法来确保至少保留一个Email对象:
# admin.py from django.contrib import admin from django.forms import BaseInlineFormSet from django.core.exceptions import ValidationError from .models import Person, Email class EmailInlineFormSet(BaseInlineFormSet): def clean(self): # 先执行父类的clean逻辑 super().clean() # 筛选出未被标记删除且验证通过的表单 kept_forms = [] for form in self.forms: # 跳过未修改的空表单(新增的未填写的表单) if form.cleaned_data.get('DELETE'): continue if form.is_valid() and not form.cleaned_data.get('DELETE'): kept_forms.append(form) # 如果没有保留的有效表单,抛出验证错误 if len(kept_forms) == 0: raise ValidationError("必须至少保留一个邮箱地址。")
2. 关联表单集到内联类
修改EmailInline,将自定义的表单集指定给它:
class EmailInline(admin.TabularInline): model = Email # 绑定自定义表单集 formset = EmailInlineFormSet @admin.register(Person) class PersonAdmin(admin.ModelAdmin): inlines = (EmailInline,)
效果说明
当你尝试删除所有内联的Email对象时,Admin页面会弹出验证错误提示,阻止提交操作,强制保留至少一个有效的邮箱记录。如果你希望自动取消第一个对象的删除标记(不提示错误),可以修改表单集的clean方法:
class EmailInlineFormSet(BaseInlineFormSet): def clean(self): super().clean() # 统计被标记删除的表单数量 deleted_count = sum(1 for form in self.forms if form.cleaned_data.get('DELETE')) # 如果所有表单都被标记删除 if deleted_count == len(self.forms): # 取消第一个表单的删除标记 self.forms[0].cleaned_data['DELETE'] = False # 清除该表单的删除相关错误 if 'DELETE' in self.forms[0].errors: del self.forms[0].errors['DELETE']
这种方式会自动保留第一个Email对象,无需用户手动取消删除操作。
内容的提问来源于stack exchange,提问作者Super Kai - Kazuya Ito
相关产品推荐
相关产品推荐

