在CBV中初始化后,我试图手动更改表单字段的名称。您可以在初始化后执行以下操作:
form = self.get_form() # it is initialized here
form.cleaned_data['name'] = form.instance.name + ' (new)'
但是我需要在验证后更改值,因此form.cleaned_data
不再涉及。我需要直接更改BoundField
的值。我怎样才能做到这一点?或者我该如何以其他方式来做我想做的事情?
以下是我的观点和形式课:
class MyView(CBV):
def form_valid(self, form):
if copy:
form.instance.pk = None
name = form.instance.name + ' (new)'
form.instance.name = name
# it does work this way
data = form.data.copy()
data['name'] = name
form.data = data
self.object = form.save()
else:
pass
return self.render_to_response(self.get_context_data(form=form))
class MyForm(forms.ModelForm):
class Meta:
model = MyModel
exclude = []
def __init__(self, *args, **kwargs):
self.copy = kwargs.get('copy', False)
super(MyForm, self).__init__(*args, **kwargs)
def clean_name(self):
# (1) doing this has no effect in the displayed form included in the response of a POST request
# (2) I don't always want to do this, only when a form is valid
cleaned_data = self.cleaned_data['name']
if self.copy:
cleaned_data['name'] += ' (new)'
return cleaned_data
答案 0 :(得分:1)
您可以覆盖清除方法。继承表单后,您可以在验证后修改您的cleaned_data。
def clean(self)
# It will validate data
self.cleaned_data = super().clean()
# do what you want
self.cleaned_data['name'] = 'blah...'
return self.cleaned_data
或者您可以在此情况下使用特定字段的名称。
def clean_name(self):
data = self.cleaned_data.get('name', '')
if not data:
raise forms.ValidationError("You must enter a name")
if not data.endswith('( new)'):
return data += '( new)'
return data
您可以在super().clean()
之后看到实际上已经<完成>完成的验证。
您可以检查打印self.is_valid()
,然后可以看到它是True。或者只是在该行中添加调试器以检查验证是否已完成
def clean(self):
# It will validate data
self.cleaned_data = super().clean()
# Check validation is already done here
# Or debugging it
# from IPython import embed; embed()
print(self.is_valid())
# do what you want
return self.cleaned_data
答案 1 :(得分:0)
您应该先使用commit=False
保存表单,然后在实例中进行更改。
def form_valid(self, form):
if copy:
instance = form.save(commit=False)
instance.pk = None
name = instance.name + ' (new)'
instance.save()
return...
(此外,发布成功后,您应该始终重定向,而不是渲染模板。)