Добавление дополнительной информации в поле формы и использование ее при отображении шаблона django - PullRequest
3 голосов
/ 07 марта 2012

Я хочу добавить дополнительную информацию для некоторых полей формы 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 %}

Я не могу использовать атрибуты виджета, так как хочу использовать информацию о свойствах вне отображаемого тега ввода.

Должен ли я создать настраиваемое поле , написать собственные средства визуализации для всех полей, которые я использую, или есть более простое решение, которое я пропустил?


Редактировать: пока мое решение: (упрощенная версия) Основной шаблон:

<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 я визуализирую поле, используя 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 (внешний вид сайта должен быть в шаблонах, а не в формах) ...

Ответы [ 3 ]

5 голосов
/ 08 марта 2012

Поле настраиваемой формы + множественное наследование + класс, в котором хранится имя класса значка

Сначала давайте определим класс, который захватываетимя класса значка.Мы назовем это 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

После того, как вы определили все пользовательские формытипы полей, которые требуются для вашей формы, обновите их вместе с ними.Затем вам нужно инициализировать icon_name для каждого поля формы в форме __init__():

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 %}

У меня нетпопробовал это сам, но это должно работать (при условии, что я вас правильно понимаю)

0 голосов
/ 07 марта 2012

Предупреждение: я только начинаю с Python и Django.

Посмотрим, поможет ли это вам начать:

class MyCustomTextInput(forms.widgets.TextInput):
    def render(self, name, value, attrs=None):
        original_html = super(MyCustomRender,self).render(name, value, attrs)
        icon_html = "<img src='/img.png' />"
        return "%s%s" % (icon_html,original_html)

class MyForm(ModelForm):
    myfield = MyCustomTextInput()

Я считаю, что это приведет к выводу, подобному:*

<img src='/img.png' /><input type="text" ... />

Взгляните на https://github.com/django/django/blob/master/django/forms/widgets.py

0 голосов
/ 07 марта 2012

Django поставляется по умолчанию с простым рендерером.

из документации Джанго :

<form action="/contact/" method="post">{% csrf_token %}
    {{ form.as_p }}
    <input type="submit" value="Submit" />
</form>

Что касается использования пользовательских изображений, Javascript будет решением, если ваша форма является динамической. Модель формы - нет, поскольку это просто представление, предназначенное для эффективного создания fomrs.

...