在这个简化的用例中,我有一个包含MyField_1
和MyField_2
的Django表单。用户填写MyField_1
。在将表单另存为模型之前,我希望计算机以编程方式添加MyField_2
,这是从另一个数据源中提取的一些数据。我目前的观点看起来像这样:
class MyCreate(CreateView):
model = MyModel
fields = ['MyField_1']
如何在保存模型之前将数据添加到MyField_2
?
答案 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)
两个建议:
lower_case_with_underscores
名称。 MyField_1
应该是my_field_1
。答案 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的说法,你应该在字段中使用强调名称,而不是驼峰。