Python 初始化和验证表单后更改BoundField值
我试图在CBV中初始化表单字段后手动更改其名称。您可以在初始化后执行此操作:Python 初始化和验证表单后更改BoundField值,python,django,django-1.8,Python,Django,Django 1.8,我试图在CBV中初始化表单字段后手动更改其名称。您可以在初始化后执行此操作: form = self.get_form() # it is initialized here form.cleaned_data['name'] = form.instance.name + ' (new)' 但我需要在验证后更改值,因此不再涉及form.cleaned_data。我需要直接更改BoundField的值。我该怎么做?或者,我怎样才能以任何其他方式做我正试图做的事情 以下是我的一些观点和形式: cl
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
您可以重写clean方法。在继承表单之后,您可以在验证之后修改您的数据
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()之后实际上已经完成了验证。
您可以检查printself.is\u valid()
,然后您可以看到它是真的。或者在该行中添加调试器以检查验证是否已完成
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
您应该首先保存表单,使用commit=False
,然后在实例中更改它
def form_valid(self, form):
if copy:
instance = form.save(commit=False)
instance.pk = None
name = instance.name + ' (new)'
instance.save()
return...
(另外,在成功发布后,您应该始终重定向,而不是呈现模板。)使用form.validated_data如何?@seuling该属性似乎不存在于表单实例中,我将其与drf混淆。请尝试清除数据或仅使用form.data-之后可以使用它validation@seuling正如我在我的问题表单中所说的那样,清理的\u数据不起作用。而且form.data
是不可变的。然后您可以自定义clean方法。或者,最好使用clean_field
方法自定义特定字段,因为我说过我不想将值设置为验证级别。验证表单时使用clean方法。我需要在验证后更改字段值(并且仅当表单有效时)。在任何情况下,即使在验证过程中,它也不起作用。好的。。。您必须先查看django表单代码。()在超级清理()方法之后,表单已验证。也不好。似乎form.data
将覆盖任何数据,甚至是已清理的数据。我尝试的唯一方法是创建不可变的form.data
的副本,并直接修改'name'
键。但这似乎不是正确的方法。@dabadaba我不确定你到底想要什么。在clean()中创建form.data或clean_数据的副本有什么区别?这就是“clean()”方法存在的原因。如果表单无效,如何防止更改?(对,我只是模拟了代码,我实际返回的响应是json)当表单无效时,form\u valid
不会被调用。这解决了你的问题吗?如果是的话,请接受答案,作为对未来搜索者的一个标志。我还没有机会尝试。别担心,如果它解决了问题,我会接受的。这也不行。确保它正在使用已更改的名称保存实例(无论如何,它已经正确地执行了此操作),但它没有使用名称字段中的正确名称在成功响应中加载表单。