在 Django 中,ModelAdmin,save_form() 和 save_formset() 有什么区别?

In Django, ModelAdmin, what is the difference between save_form() and save_formset()?

有人可以解释 ModelAdmin 中 save_form 和 save_form 之间的差异 and/or 相似之处吗?

我唯一能找到的是源代码。

def save_form(self, request, form, change):
        """
        Given a ModelForm return an unsaved instance. ``change`` is True if
        the object is being changed, and False if it's being added.
        """
        return form.save(commit=False)


def save_formset(self, request, form, formset, change):
        """
        Given an inline formset save it to the database.
        """
        formset.save()

文档只有关于 save_formset (https://docs.djangoproject.com/en/4.0/ref/contrib/admin/#django.contrib.admin.ModelAdmin.save_formset)

The save_formset method is given the HttpRequest, the parent ModelForm instance and a boolean value based on whether it is adding or changing the parent object.

一个formset是一堆相等的形式。例如,如果您有一个表单,用户可以在其中输入他喜欢的食物,但是您希望用户能够继续添加更多,想添加多少就添加多少,那么表单集将生成带有食物输入的表单,并且将随着列表的增长,生成新的空白输入。当 formset.save() 被调用时,所有这些表格都会被保存,这就是 save_formset() 正在做的事情。

docs 中的示例所示,您可以覆盖它,例如在将更改提交到数据库之前向表单集中的每个表单添加一个用户:

class ArticleAdmin(admin.ModelAdmin):
    def save_formset(self, request, form, formset, change):
        instances = formset.save(commit=False)
        for obj in formset.deleted_objects:
            obj.delete()
        for instance in instances:
            instance.user = request.user
            instance.save()
        formset.save_m2m()

现在,save_form()只是保存一个普通的表格,但是你可以看到它有commit=False,所以表格还没有保存到数据库中。可以将数据添加到表单,直到它准备好提交到数据库。如果表单基于具有 ManyToManyField 的模型,则在首次保存模型实例之前无法保存该字段,因此这就是 form.save_m2m() 在同一 source code 中的以下函数中的位置:

def save_related(self, request, form, formsets, change):
        """
        Given the ``HttpRequest``, the parent ``ModelForm`` instance, the
        list of inline formsets and a boolean value based on whether the
        parent is being added or changed, save the related objects to the
        database. Note that at this point save_form() and save_model() have
        already been called.
        """
        form.save_m2m()
        for formset in formsets:
            self.save_formset(request, form, formset, change=change)

备注 我对表单集比较陌生,我自己从未修改或使用过 ModelAdmin methods,所以如果有人发现我的摘要有任何错误,请告诉我。