如何强制保存"空"/未更改的django admin内联?

Dan*_*iel 27 django inline django-admin

我在我的一个管理模型中有一些内联,它们具有默认值,当使用"添加另一个..."添加新实例时可能不需要更改.不幸的是,除非某些值发生变化,否则django不会将这些内联识别为新对象.这会强制我添加内联,更改任意值,保存,更改值并再次保存以达到所需效果.

到目前为止我唯一提出的解决方案是添加一个隐藏的"已更改"字段,它将在添加新内联时通过java脚本填充.因为这感觉非常hackish,我希望有一个更优雅的解决方案.

任何想法将不胜感激.

谢谢,丹尼尔.

Dan*_*iel 56

我花了很长时间才弄明白,但实际上这很简单.

from django.contrib import admin
from django.forms.models import BaseInlineFormSet, ModelForm

class AlwaysChangedModelForm(ModelForm):
    def has_changed(self):
        """ Should returns True if data differs from initial. 
        By always returning true even unchanged inlines will get validated and saved."""
        return True

class CheckerInline(admin.StackedInline):
    """ Base class for checker inlines """
    extra = 0
    form = AlwaysChangedModelForm
Run Code Online (Sandbox Code Playgroud)

  • 我不会说明显,但绝对简单而且棒极了! (5认同)

Har*_*ons 7

@daniel答案很棒,但是如果没有进行任何更改,它将尝试保存已经创建的实例,这是不必要的,更好地使用它,如:

class AlwaysChangedModelForm(ModelForm):
    def has_changed(self, *args, **kwargs):
        if self.instance.pk is None:
            return True
        return super(AlwaysChangedModelForm, self).has_changed(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)

  • 我尝试了这个,“self.instance.pk”有时是一个空白字符串(不是 None),所以我不得不将其更改为“if not self.instance.pk:”。此外,has_changed 方法(从 ModelForm->BaseForm)没有任何额外的 *args 或 **kwargs,因此 pylint 会发出有关此方法没有参数的警告。否则工作得很好! (2认同)

小智 5

@Daniels、@HardQuestions' 和 @jonespm 的综合答案:

class MarkNewInstancesAsChangedModelForm(forms.ModelForm):
    def has_changed(self):
        """Returns True for new instances, calls super() for ones that exist in db.
        Prevents forms with defaults being recognized as empty/unchanged."""
        return not self.instance.pk or super().has_changed()
Run Code Online (Sandbox Code Playgroud)