python-在表单字段中添加额外信息,并在渲染Django模板时使用它

提问

我想为Django表单的某些字段添加额外的信息,并在模板中使用它来添加一些额外的html标签

我有一个django形式,例如:

class MyForm(forms.Form):
    integer = forms.IntegerField(
        help_text='Please enter your favorite integer number',
        label='Favorite integer',
        widget=forms.TextInput(attrs={'class':'input-xlarge'}))
    decimal = forms.DecimalField(
        min_value=Decimal('0.0001'),
        decimal_places=4,
        help_text='Please enter your favorite decimal number',
        label='Favorite decimal',
        widget=forms.TextInput(attrs={'class':'input-xlarge'}))
    ==> here I would like to say: decimal will have a new property

我在模板中渲染MyForm,在每个字段上使用循环:

{% for item in form.visible_fields %}
  ==> here I would like to test if item has that property to add some html tags
  {{ item }}
{% endfor %}

我无法使用小部件的attrs,因为我想在呈现的输入标签之外使用属性信息.

我应该create a custom field,为我使用的所有字段编写自定义渲染器,还是我错过了一个更简单的解决方案?

编辑:到目前为止,我的解决方案是:(简化版)
主模板:

<form action="/somewhere/" method="post">{% csrf_token %}
 {% include 'form_field.html' with item=form.integer icon="icon-home" %}
 {% include 'form_field.html' with item=form.decimal icon="icon-list-alt" %}
 {% include 'form_field.html' with item=form.another icon="icon-signal" %}
 {% include 'form_field.html' with item=form.again   icon="icon-time" %}
 ...

在form_field.html中,我使用Twitter’s Bootstrap input-prepend div渲染字段:

<div class="control-group">
  <label class="control-label" for="{{ item.name }}">{{ item.label }}</label>
  <div class="controls">
    {% if icon %}
      <div class="input-prepend">
      <span class="add-on"><i class="{{ icon }}"></i></span>
    {% endif %}
      {{ item }}
      <p class="help-block">{{ item.help_text }}</p>
    {% if icon %}
    </div>
    {% endif %}
  </div>
</div>

我想要的只是使用循环而不是枚举所有字段来简化主模板,这容易出错.因此,我想将“ icon-home”属性从模板移动到表单定义,以将所有属性放在同一位置(特定的窗口小部件属性已在表单中).
理想情况下,在主模板中,我将具有:

{% for item in form.visible_fields %}
  {% include 'form_field.html' %}
{% endfor %}

我了解它可以被视为对Django原理的误解(站点外观应在模板中,而不是在形式中)…

最佳答案

自定义表单字段多重继承一个存储图标类名称的类

首先,让我们定义一个捕获图标类名称的类.我们称其为IconName:

class IconName(object):
    def get_icon_name(self):
        return self._icon_name
    def set_icon_name(self, value):
        self._icon_name = value
    icon_name = property(get_icon_name, set_icon_name)

您需要为使用的每种表单字段类型提供自定义字段类型.这是使用IntegerField完成的.您的自定义字段类需要继承原始的django表单字段类(在本例中为IntegerField)和IconName类.

class CustomCharField(CharField, IconName):
    pass

定义表单所需的所有自定义表单字段类型后,请使用它们更新表单.接下来,您需要为表单的__init __()中的每个表单字段初始化icon_name:

def __init__(self, *args, **kwargs):
    super(forms.Form, self).__init__(*args, **kwargs)
    self.fields['integer'].icon_name = 'icon-home'
    ...

在模板中,您可以执行以下操作:

{% for item in form.visible_fields %}
<div class="control-group">
  <label class="control-label" for="{{ item.name }}">{{ item.label }}</label>
  <div class="controls">
    {% if item.field.icon_name %}
      <div class="input-prepend">
      <span class="add-on"><i class="{{ item.field.icon_name }}"></i></span>
    {% endif %}
      {{ item }}
      <p class="help-block">{{ item.help_text }}</p>
    {% if item.field.icon_name %}
    </div>
    {% endif %}
  </div>
</div>
{% endfor %}

我自己没有尝试过,但是应该可以(假设我正确理解了您的意思)

评论