使用更改 django 模板中表单字段的名称属性
Posted
技术标签:
【中文标题】使用更改 django 模板中表单字段的名称属性【英文标题】:Change the name attribute of form field in django template using 【发布时间】:2012-08-10 10:21:53 【问题描述】:我有表单字段 form.item 将呈现给
<input type="text" name="item" >
如何使用自定义模板标签更改表单字段的名称属性?
我尝试将表单发送到模板标签哪里
form.fields['item'].widget.attrs['name'] = 'new_name'
但我没有成功。
我需要更改模板中的名称属性。
更新
models.py
class A(models.Model):
name = models.CharField(50)
type = models.CharField(50)
class B(models.Model):
field1 = ForeignKeyField(A)
value = IntegerField()
views.py
def saving_calculation(request):
SavingFormset = modelformset_factory(A, extra=2)
OfferInlineFormSet = inlineformset_factory(
A, B,
extra = 4
)
if request.method == 'POST':
pass
else:
offer_formset = OfferInlineFormSet()
saving_formset = SavingFormset(queryset=SavingCalculation.objects.none())
return render_to_response(
'purchasing/saving_calculation.html',
'offer_formset':offer_formset,
'saving_formset':saving_formset,
模板
<form action="." method="POST">
offer_formset.management_form
saving_formset.management_form
saving_formset.prefix
<table>
<thead>
<tr>
<th>Business Unit</th>
<th>Category</th>
<th>Buyer</th>
<th>Offer1</th>
<th>Offer2</th>
<th>Offer3</th>
<th>Offer4</th>
</tr>
</thead>
<tbody>
% for saving in saving_formset.forms %
<tr>
<td>saving.businessunit</td>
<td>saving.type_of_purchase</td>
<td>saving.buyer</td>
% for offer in offer_formset.forms %
<td> offer|set_field_attr:forloop.counter0 </td>
</tr>
% endfor %
% endfor %
</tbody>
</table>
<input type="submit" value="Save" />
</form>
现在在自定义模板标签中,我需要为内联表单集的每个字段分配新名称
【问题讨论】:
Override Django form field's name attr的可能重复 为什么要改名?是什么让你觉得你需要这个? 呃,什么?这些都不是使用动态名称的理由。解释您的用例,以及标准视图/表单集结构未涵盖它的原因。 @Daniel:我想实现这个***.com/questions/11929355/… @DanielRoseman:我更新了问题 【参考方案1】:另一种方式,创建一个接受名为“name”的新参数的自定义输入[我还创建了一个使用此输入的自定义字段]:
class CustomNameTextInput(forms.TextInput):
def __init__(self, *args, **kwargs):
self.name = kwargs.pop('name')
super().__init__(*args, **kwargs)
def render(self, name, value, attrs, renderer):
return super().render(self.name, value, attrs, renderer)
class ElementField(forms.CharField):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.widget = CustomNameTextInput(name='name')
【讨论】:
【参考方案2】:from django.forms.widgets import Input, TextInput
class CustomInput(Input):
def get_context(self, name, value, attrs):
context = super(CustomInput, self).get_context(name, value, attrs)
if context['widget']['attrs'].get('name') is not None:
context['widget']['name'] = context['widget']['attrs']['name']
return context
class CustomTextInput(TextInput, CustomInput):
pass
class ClientLoginForm(forms.Form):
username = forms.CharField(label='CustomLabel', widget=CustomTextInput(attrs='class': 'form-control','name': 'CustomName'))
【讨论】:
【参考方案3】:我已经用几种不同的方式对此进行了测试,它适用于多种类型的表单字段。
在要设置名称的每个字段上使用set_field_html_name(...)
。
from django import forms
from django.core.exceptions import ValidationError
def set_field_html_name(cls, new_name):
"""
This creates wrapper around the normal widget rendering,
allowing for a custom field name (new_name).
"""
old_render = cls.widget.render
def _widget_render_wrapper(name, value, attrs=None):
return old_render(new_name, value, attrs)
cls.widget.render = _widget_render_wrapper
class MyForm(forms.Form):
field1 = forms.CharField()
# After creating the field, call the wrapper with your new field name.
set_field_html_name(field1, 'new_name')
def clean_field1(self):
# The form field will be submit with the new name (instead of the name "field1").
data = self.data['new_name']
if data:
raise ValidationError('Missing input')
return data
【讨论】:
【参考方案4】:class MyForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
super(MyForm, self).__init__(*args, **kwargs)
self.fields['field_name'].label = "New Field name"
【讨论】:
这会更改字段标签,而不是字段名称(<input name="NAME"/>
的“NAME”部分)【参考方案5】:
您可以根据需要对任何小部件类进行子类化并创建自己的“渲染方法”。 示例在 PATH_TO_YOUR_DJANGO/django/forms/forms.py
class CustomNameTextInput(TextInput):
def render(self, name, value, attrs=None):
if 'name' in attrs:
name = attrs['name']
del attrs['name']
return super(TextInput, self).render(name, value, attrs)
class MyForm(Form):
item = CharField(widget=CustomNameTextInput, attrs='name':'my_name')
【讨论】:
我没有看到您在哪里为字段名称属性指定新名称【参考方案6】:form.fields['new_name'] = form.fields['item']
del form.fields['item']
【讨论】:
@Sergy :我已经尝试过这个,但在我的情况下这不起作用,因为我正在处理表单集以上是关于使用更改 django 模板中表单字段的名称属性的主要内容,如果未能解决你的问题,请参考以下文章