在保存之前将数据添加到Django表单中?

时间:2017-07-20 17:07:51

标签: django django-models django-forms django-views

在这个简化的用例中,我有一个包含MyField_1MyField_2的Django表单。用户填写MyField_1。在将表单另存为模型之前,我希望计算机以编程方式添加MyField_2,这是从另一个数据源中提取的一些数据。我目前的观点看起来像这样:

class MyCreate(CreateView):
    model = MyModel
    fields = ['MyField_1']

如何在保存模型之前将数据添加到MyField_2

3 个答案:

答案 0 :(得分:5)

有多种方法可以执行此操作(例如覆盖ModelForm.save()方法),但我推荐的方法是覆盖ModelFormMixin.form_valid()方法。所以改变你的观点:

class MyCreate(CreateView):
  model = MyModel
  fields = ['MyField_1']

  def form_valid(self, form):
    self.object = form.save(commit=False)
    self.object.MyField_2 = 43
    self.object.save()
    return super(ModelFormMixin, self).form_valid(form)

两个建议:

答案 1 :(得分:2)

您可以执行此操作(请参阅基于类视图的第二个示例):

if request.method == 'POST':
    form = Form(request.POST)
    if form.is_valid():
        instance = form.save(commit=False)
        instance.my_field_2 = #Put value here
        instance.save()
        return #Put return here
else:
    form = Form()

这样您就可以初始化任何值以形成哪个用户不输入。

在基于班级的CreateView中,您可以通过以下方式覆盖form_valid方法:

def form_valid(self, form):
    form.instance.field_2 = # Put value here
    return super(YourCreateView, self).form_valid(form)

答案 2 :(得分:1)

我会覆盖ModelForm.save()或模型save()。你应该尽可能地将你的逻辑推向模型。如果您只是在没有MyField_2的情况下创建此模型的实例,那么您应该覆盖模型save()。这遵循面向对象编程的封装实践,当正确完成时是非常美好的事情。

class MyModelForm(forms.ModelForm):
    model = MyModel
    fields = ["field_1"]
    # no changes needed in form because the model itself will handle auto-population of field_2.

class MyModel(models.Model):
    field_1 = models.SomeFieldType(...)
    field_2 = models.SomeFieldType(...)

    def save(self, *args, **kwargs):
        if self.id: # If true, this is being created. If false, this is just being edited and it already exists.
            # auto populate field_2
        else:
            # it's being edited and already exists so I'm guessing we just want this to do the default logic.
            super(MyModel, self).save(*args, **kwargs)

如果你真的想要,你甚至可以通过模型传递变量保存方法** kwargs告诉逻辑它是由表单创建的。在这种情况下,您执行自动填充但如果它不是由表单创建的,则可以选择不自动填充field_2

注意:我同意@sarafeim的说法,你应该在字段中使用强调名称,而不是驼峰。