【问题标题】:Using inline in ModelForm in Django admin to validate many-to-many inline field (by overriding the clean() method)在 Django 管理中使用 ModelForm 中的内联来验证多对多内联字段(通过覆盖 clean() 方法)
【发布时间】:2021-10-28 15:20:29
【问题描述】:

我想通过覆盖 clean 方法来验证 Django 管理中的多对多字段。

thread 提供了一种方法,方法是创建一个 ModelForm,然后在那里进行清理。但是,我的问题是多对多字段是内联的,即我有一个表格内联,而不是您必须选择多个元素的小部件。

我想知道是否有人知道如何在 ModelForm 中添加内联,以便我可以进行清理和验证。我见过人们谈论 inlineformset_factory,但它总是与 views.py 相关,而不是管理员(我不知道我什至会如何覆盖它的 clean 方法)。

我在下面添加了一些代码:

class ProductVariantForm(ModelForm):
    class Meta:
        model = ProductVariant

        fields = [  'name',
                    'price',
                 ]

        # I then want to be able to add something like
        # inlines = [OptionValueInline,]
        # for the inline many-to-many field. 

    def clean(self):
        # Check if list of option_values is ok.

class ProductVariantAdmin(admin.ModelAdmin):
    form = ProductVariantForm

【问题讨论】:

    标签: django django-models django-forms many-to-many inline-formset


    【解决方案1】:

    添加内联是 Admin 本身的一项功能。有关内联的更多信息,请参阅this doc。 Afaik,您不能仅将内联添加到普通表单(或 ModelForm)。

    要检查内联数据的有效性,您可以使用InlineModelAdmin 类的form 属性。这样就可以直接访问内联表单的clean方法了。

    详细地说,它是这样拆分的,因为内联在 Django 的术语中是一个单独的形式,涉及不同的数据并运行单独的查询。它们都在一个 HTTP 请求中提交,但这就是它们的共同点。因此,将 main ModelForm 用于内联数据实际上没有任何意义。

    【讨论】:

    • 感谢米哈尔的回复。很明显,我在叫错树。我尝试按照您的建议进行操作,但在如何使用 form 属性或如何访问其 clean 方法上陷入困境。但是,我确实找到了一个解决方案(这可能是您所说的,我不确定)并使用了 BaseInlineFormSet 然后覆盖了其中的 clean 方法。
    【解决方案2】:

    我对该问题的解决方案是基于this 的帖子。

    class ProductVariantOptionValueInlineFormSet(BaseInlineFormSet):
        def clean(self):
            super().clean()
            data = self.cleaned_data
            # do whatever validation on data here
    
    class ProductVariantOptionValueInline(admin.TabularInline):
        model = ProductVariant.option_values.through
        formset = ProductVariantOptionValueInlineFormSet
    
    class ProductVariantAdmin(admin.ModelAdmin):
        inlines = [
            ProductVariantOptionValueInline,
        ]
    
        exclude = ('option_values',)
    

    【讨论】:

      猜你喜欢
      • 2011-03-10
      • 2019-08-08
      • 1970-01-01
      • 2011-11-10
      • 1970-01-01
      • 1970-01-01
      • 2016-01-03
      • 2014-03-01
      • 1970-01-01
      相关资源
      最近更新 更多