Django:在这种情况下我可以省略“.save(commit=False)”吗?

Django: can I omit ".save(commit=False)" in this case?

这是 Django 中 ModelForm 的视图函数的片段:

if form.is_valid():
    new_entry = form.save(commit=False)
    new_entry.topic = topic
    new_entry.save()

将此代码替换为以下代码是否会产生相同的效果?:

if form.is_valid():
    form.topic = topic
    form.save()

如果是这样,像第一个例子那样创建 new_entry 对象有什么用?

Would substituting this code with the following one have the same effect?:

否,form.save returns 模型实例,设置form.topic 不改变此模型。你可以做的是:

if form.is_valid():
    form.instance.topic = topic
    new_entry = form.save()

但请确保您的表单中没有 topic 作为字段,否则 .save 可能会覆盖您刚刚设置的内容。

另一种方法是将带有主题的实例传递给表单。

instance = MyModel(topic=topic)
form = MyForm(request.POST, instance=instance)
if form.is_valid():
    new_entry = form.save()

Would substituting this code with the following one have the same effect?

显然不是 - 您的 form 对象不是 form.save() 返回的模型实例。您当前(第一个片段)的解决方案是官方规范解决方案,另一种选择是将主题传递给表单并覆盖表单的 save() 方法来处理它:

# yourforms.py
class MyForm(forms.ModelForm):

    # your existing code here

    def __init__(self, *args, **kw):
        # if "topic" is required for your model, 
        # you may want to either have a default value
        # for "topic" or raise if it's not passed.
        self.topic = kw.pop("topic", None)
        super(MyForm, self).__init__(*args, **kw)

   def save(self, commit=False):
       instance = super(MyForm, self).save(commit=commit)
       instance.topic = self.topic
       if commit:
           instance.save()
       return instance

在您看来:

# your existing code here    
form = MyForm(request.POST, ..., topic=topic)
if form.is_valid():
    new_entry = form.save()

如您所见,它并没有使代码总体上更简单 - 实际上,与保存在视图中相比,你要添加到表单的(有点)更多 - 但至少它使视图代码更清晰(恕我直言)。

请注意,在这种情况下,new_entry 变量仅在稍后在视图中需要时才有用,否则您可以省略它。