【问题标题】:How to force-save an "empty"/unchanged django admin inline?如何强制保存“空”/未更改的 django 管理员内联?
【发布时间】:2011-04-09 03:12:04
【问题描述】:

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

到目前为止,我想出的唯一解决方案是添加一个隐藏的“已更改”字段,在添加新内联时将通过 JavaScript 填充该字段。由于这感觉很hackish,我希望有一个更优雅的解决方案。

【问题讨论】:

    标签: django django-admin inline


    【解决方案1】:

    我花了很长时间才弄明白,但实际上真的很简单。

    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
    

    【讨论】:

    • 我不会说很明显,但绝对简单而且很棒!
    【解决方案2】:

    @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)
    

    【讨论】:

    • 我试过这个,self.instance.pk 有时是一个空白字符串(不是无),所以我不得不把它改成if not self.instance.pk:。此外,has_changed 方法(来自 ModelForm->BaseForm)没有任何额外的 *args 或 **kwargs,因此 pylint 会警告此方法没有参数。否则效果很好!
    【解决方案3】:

    结合@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()
    

    【讨论】:

    • 虽然此代码可以解决问题,including an explanation 说明如何以及为什么解决问题将真正有助于提高您的帖子质量,并可能导致更多的赞成票。请记住,您正在为将来的读者回答问题,而不仅仅是现在提问的人。请edit您的回答添加解释并说明适用的限制和假设。
    猜你喜欢
    • 2011-06-02
    • 2015-06-21
    • 1970-01-01
    • 1970-01-01
    • 2013-08-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-28
    相关资源
    最近更新 更多