有没有办法同时覆盖inlines表单和parent的save方法?
我想在用户保存已编辑的内联表单时更改字段的值。
谢谢:)
答案 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
方法,这几乎总是一种更好的方法。