【问题标题】:Change the name attribute of form field in django template using使用更改 django 模板中表单字段的名称属性
【发布时间】: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>

现在在自定义模板标签中,我需要为内联表单集的每个字段分配新名称

【问题讨论】:

标签: python django django-forms django-templates django-views


【解决方案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"
        

        【讨论】:

        • 这会更改字段标签,而不是字段名称(&lt;input name="NAME"/&gt; 的“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 :我已经尝试过这个,但在我的情况下这不起作用,因为我正在处理表单集
        猜你喜欢
        • 2017-01-31
        • 2021-09-09
        • 2012-06-05
        • 2011-06-26
        • 2010-12-31
        • 2016-12-24
        • 2012-09-11
        • 2014-08-25
        • 2019-09-01
        相关资源
        最近更新 更多