情景:
我有这样的模特:
class A(models.Model):
...
class B(models.Model):
a = models.ForeignKey(A)
...
在管理员中我有这样的事情:
class AInlinde(admin.StackedInline):
...
model = A
...
class BAdmin(admin.ModelAdmin):
...
inlines = [AInline]
...
现在我需要在用户删除内联中的某个模型时记录日志,但我无法遵循代码,直到现在,我知道Badmin
有一个方法:save_formset
,这就是:
def save_formset(self, request, form, formset, change):
"""
Given an inline formset save it to the database.
"""
formset.save()
但我认为formset
是通过方法modelformset_factory
生成的,所以我不知道何时可以覆盖该formset的删除行为
答案 0 :(得分:2)
覆盖formset如何保存或删除对象的最佳方法是创建一个继承自BaseInlineFormSet
的类并覆盖方法save
和save_existing_objects
:
class NoDeleteFormset(BaseInlineFormSet):
def save(self, commit=True, request=None):
"""Saves model instances for every form, adding and changing instances
as necessary, and returns the list of instances.
"""
if not commit:
self.saved_forms = []
def save_m2m():
for form in self.saved_forms:
form.save_m2m()
self.save_m2m = save_m2m
return self.save_existing_objects(commit) + self.save_new_objects(commit)
def save_existing_objects(self, commit=True, request=None):
self.changed_objects = []
self.deleted_objects = []
if not self.initial_forms:
return []
saved_instances = []
for form in self.initial_forms:
pk_name = self._pk_field.name
raw_pk_value = form._raw_value(pk_name)
# clean() for different types of PK fields can sometimes return
# the model instance, and sometimes the PK. Handle either.
pk_value = form.fields[pk_name].clean(raw_pk_value)
pk_value = getattr(pk_value, 'pk', pk_value)
obj = self._existing_object(pk_value)
if self.can_delete and self._should_delete_form(form):
self.deleted_objects.append(obj)
obj.deleted_at = datetime.now()
obj.save()
# log there your user deleting the object!
continue
if form.has_changed():
self.changed_objects.append((obj, form.changed_data))
saved_instances.append(self.save_existing(form, obj, commit=commit))
if not commit:
self.saved_forms.append(form)
return saved_instances
然后构造一个类而不是继承自StackedInline
:
class MetaInline(StackedInline):
formset = NoDeleteFormset
...
答案 1 :(得分:2)
对于在2017年寻找软删除和记录删除的任何人。 现在在django 1.11中你可以覆盖 delete_existing 方法
class SoftDeleteModelFormSet(BaseModelFormSet):
def delete_existing(self, obj, commit=True):
"""Deletes an existing model instance."""
if commit:
obj.deleted_at = datetime.datetime.now()
obj.save()
# log here
class SoftDeleteInlineFormSet(BaseInlineFormSet):
def delete_existing(self, obj, commit=True):
"""Deletes an existing model instance."""
if commit:
obj.deleted_at = datetime.datetime.now()
obj.save()
# log here
使用带有新formset的modelformset_factory
product_formset = modelformset_factory(
...
formset = SoftDeleteModelFormSet,
...
)
答案 2 :(得分:0)
您不需要自定义默认的ModelAdmin
删除行为,只需连接到django.db.models.signals.post_delete
并在模型删除后获取模型并将其记录在那里。