Django在初始化表单后设置字段值
我试图在表单初始化后将字段设置为某个值 例如,我有下面的课程Django在初始化表单后设置字段值,django,Django,我试图在表单初始化后将字段设置为某个值 例如,我有下面的课程 class CustomForm(forms.Form): Email = forms.EmailField(min_length=1, max_length=200) 在我看来,我希望能够做到以下几点: form = CustomForm() form["Email"] = GetEmailString() return HttpResponse(t.render(c)) 因为您没有传递POST数据,所以我假设您尝试做
class CustomForm(forms.Form):
Email = forms.EmailField(min_length=1, max_length=200)
在我看来,我希望能够做到以下几点:
form = CustomForm()
form["Email"] = GetEmailString()
return HttpResponse(t.render(c))
因为您没有传递POST数据,所以我假设您尝试做的是设置一个初始值,该值将显示在表单中。这样做的方式是使用
initial
关键字
form = CustomForm(initial={'Email': GetEmailString()})
有关更多说明,请参阅
如果您试图在提交表单后更改值,可以使用以下方法:
if form.is_valid():
form.cleaned_data['Email'] = GetEmailString()
如果您已经初始化表单(包含或不包含数据),并且需要在显示表单之前添加更多数据,请查看上述参考文档,以了解有关使用清洁数据的其他方法的更多信息:
form = Form(request.POST.form)
form.data['Email'] = GetEmailString()
如果已经初始化表单,则可以使用字段的initial属性。比如说,
form = CustomForm()
form.fields["Email"].initial = GetEmailString()
如果将数据添加到所收集的表单数据集的副本中,则类似Nigel Cohen的方法会起作用:
form = FormType(request.POST)
if request.method == "POST":
formcopy = form(request.POST.copy())
formcopy.data['Email'] = GetEmailString()
如果出于某种原因希望在表单的
\uuuu init\uuu
方法中执行此操作,可以操作initial
dict:
class MyForm(forms.Form):
my_field = forms.CharField(max_length=255)
def __init__(self, *args, **kwargs):
super(MyForm, self).__init__(*args, **kwargs)
self.initial['my_field'] = 'Initial value'
只需更改表单。数据字段:
class ChooseProjectForm(forms.Form):
project = forms.ModelChoiceField(queryset=project_qs)
my_projects = forms.BooleanField()
def __init__(self, *args, **kwargs):
super(ChooseProjectForm, self).__init__(*args, **kwargs)
self.data = self.data.copy() # IMPORTANT, self.data is immutable
# any condition:
if self.data.get('my_projects'):
my_projects = self.fields['project'].queryset.filter(my=True)
self.fields['project'].queryset = my_projects
self.fields['project'].initial = my_projects.first().pk
self.fields['project'].empty_label = None # disable "-----"
self.data.update(project=my_projects.first().pk) # Update Form data
self.fields['project'].widget = forms.HiddenInput() # Hide if you want
把另一种方式加入到混合中:这也可以,用一种更现代的符号。它只是围绕着这样一个事实工作:
QueryDict
是不可变的
>>> the_form.data = {**f.data.dict(), 'some_field': 47}
>>> the_form['some_field'].as_widget()
'<input type="hidden" name="some_field" value="47"
class="field-some_field" id="id_some_field">'
>>表单.data={**f.data.dict(),'some_field':47}
>>>_表单['some_field'].as_widget()
''
如果您已经像这样初始化了表单
form = CustomForm()
从2019年1月起,正确的方法是使用.initial
替换数据。这将替换表单附带的initial
dict中的数据。如果您已经使用一些实例进行了初始化,例如form=CustomForm(instance=instance)
要替换表单中的数据,您需要
form.initial['Email'] = GetEmailString()
概括起来就是,
form.initial['field_name'] = new_value
在小部件中使用“值”属性。 例如:
username=forms.CharField(
必需=错误,
widget=forms.TextInput(attrs={'readonly':True,'value':'CONSTANT_value'}),
)
这对我来说是失败的。我在表单的init方法中有一行与上面类似的代码,它会引发“AttributeError:This QueryDict instance is immutable”(AttributeError:This QueryDict instance is immutable)。只有在初始化表单时没有任何表单数据,此代码才有效。因此,像request.GET或request.POST这样的不可变对象将不会被绑定,因此您将得到一个空字典(form.data),可以在没有任何错误的情况下对其进行更改。仅供参考,我使用的是Django 1.6.3如果您的“内容类型”标题设置为“多部分/表单数据”,则此功能将正常工作。当您使用“application/x-www-form-urlencoded”的内容类型时,它会失败。我不知道为什么,但这是一个需要调试的******。这证实了我所知道的,但是当我给它一个初始值时,我的ModelChoiceField
仍然给它一个无效的选择:(是的,这也是我的问题。改变form.data['Email']是不可能的。我把我的更改为form.data['Email']=GetEmailString()
并且它可以工作我需要将它设置在CustomForm(request.POST)和.is_valid()之间,因此我不能在构造函数中使用initial,也不能使用清理后的_数据。我尝试使用form.data,但它是不可变的(Django 1.11)。这个问题的正确解决方案应该是:form.fields['Email'].initial=GetEmailString()
form.fields['keyword'].initial
允许您在实例化表单后初始化值。我不太喜欢覆盖原始数据。如果您一定要这样做,您可能应该执行data[form.add_prefix('Email')]
考虑设置前缀的情况。Django 1.7/Python 3.4是否有其他方法实现这一点?这不适用于方法如果不需要保留原始表单,第三行可以稍微短一点:form.data=form.data.copy()
@Josh,这是一个需要的场景:使用表单验证输入->处理输入->处理完成->删除/修改表单的多个字段,并作为响应呈现为HTML。例如,表单中有“名称”、“电子邮件”、“内容”字段,我想保留“名称”和“电子邮件”,但删除“内容”。这样用户就不需要输入如果他们想提交另一篇文章,请再次输入姓名/电子邮件。当然,使用与初始值相同的姓名/电子邮件初始化新表单是一种方法,但我认为在某些情况下删除旧表单更简单。我不确定我是否完全理解。但是,如果我理解,我觉得你应该使用modelform\u factory
y您可以生成一个不包含不需要的字段的表单类。如果表单类包含未呈现的字段,则表单对象仍将接受未呈现字段的数据,这是非常危险的。攻击者可以利用这一点发挥其优势。在带有表单集的for循环中也非常有效,只需使用逻辑即可“for form in formset”,您可以如上所示设置选项和初始数据。Django 1.7/Python 3.4中是否有其他方法可以实现这一点?这不适用于me@JeremyCraigMartinez:否…是尝试绑定表单的表单(传入GET/POST数据)?文档说这就是为什么只显示未绑定表单的初始值。对于绑定表单,HTML输出将使用绑定数据。请参阅正确的方式是表单。initial[“Email”]=GetEmailString()最终找到了解决方案。谢谢。这对我来说很有效。