django admin在内联中覆盖保存方法?

时间:2009-09-03 23:57:39

标签: django django-admin

有没有办法同时覆盖inlines表单和parent的save方法?

我想在用户保存已编辑的内联表单时更改字段的值。

谢谢:)

2 个答案:

答案 0 :(得分:9)

要自定义内联保存,可以覆盖FormSet

class SomeInlineFormSet(BaseInlineFormSet):
    def save_new(self, form, commit=True):
        return super(SomeInlineFormSet, self).save_new(form, commit=commit)

    def save_existing(self, form, instance, commit=True):
        return form.save(commit=commit)

class SomeInline(admin.StackedInline):
    formset = SomeInlineFormSet
    # ....

请注意,save_new()仅使用表单来获取数据,但不允许ModelForm提交数据。相反,它构建了模型本身。这允许它插入父关系,因为它们在表单中不存在。这就是为什么覆盖form.save()不起作用。

对于通用内联,永远不会调用form.save()方法,而是使用form.cleaned_data来获取所有值,Field.save_form_data()用于存储模型中的值实例


仅供参考,一些一般性提示将这些事情弄清楚;拥有一个IDE(或者可能是vim配置或Sublime设置)非常有价值,它允许非常容易地跳转到符号定义。上面的代码是通过跳转到内联/ formset代码,并看看发生了什么来计算出来的。在PyCharm的情况下,通过按住Command(或Ctrl)并单击符号来工作。如果您是vim用户,ctags可能会为您做类似的事情。

答案 1 :(得分:2)

一种方法是挂钩你的内联模型的'pre_save'信号:

from django.db.models.signals import pre_save
from your_app.models import YourModel

def callback(sender, **kwargs):
    # 'instance' is the model instance that is about to be saved,
    # so you can do whatever you want to it.
    instance.field = new_value

pre_save.connect(callback, sender=YourModel)

但我不确定为什么你不能覆盖save方法,这几乎总是一种更好的方法。