Задать вопрос

Как в WTForms отобразить список checkbox?

В WTForms нет из коробки chexbox.
Нашел способ выводить их здесь.
Делаю так:
forms.py:
class MultiCheckboxField(SelectMultipleField):
	widget = widgets.ListWidget(prefix_label=False)
	option_widget = widgets.CheckboxInput()

class BrifStoreForm(Form):
choices = [(1, 'one'),
           (2, 'two'),
           (3, 'tree')]
resident = MultiCheckboxField('Label',
                              choices=choices, 
                              coerce=int)


app.py:
from flask import Flask, render_template, request
from forms import BrifStoreForm

app = Flask(__name__)
app.config.from_object('config')

@app.route('/', methods=['GET', 'POST'])
def brif_store():
	form = BrifStoreForm()
	if request.method == 'GET':
		return render_template('brif-store.html',
		                       form=form)
	elif request.method == 'POST' and form.validate_on_submit():
		return render_template('result-form.html',
		                       form=form)
	return render_template('brif-store.html',
	                       form=form)

if __name__ == '__main__':
	app.run()


result-form.html:
{% if form.resident.data %}
        {{ form.resident.data }}
    {% endif %}

И все получается, выводятся checkbox'ы как и хотелось. Далее я передаю результаты формы в шаблон jinja2, но вместо выбранных значений у меня отображаются ключи, в таком виде [1, 2]. Как вывести значения выбранных чекбоксов?
Я так понимаю нужно переопределить родительский класс SelectMultipleFields. Вот он:
class SelectMultipleField(SelectField):
    """
    No different from a normal select field, except this one can take (and
    validate) multiple choices.  You'll need to specify the HTML `size`
    attribute to the select field when rendering.
    """
    widget = widgets.Select(multiple=True)

    def iter_choices(self):
        for value, label in self.choices:
            selected = self.data is not None and self.coerce(value) in self.data
            yield (value, label, selected)

    def process_data(self, value):
        try:
            self.data = list(self.coerce(v) for v in value)
        except (ValueError, TypeError):
            self.data = None

    def process_formdata(self, valuelist):
        try:
            self.data = list(self.coerce(x) for x in valuelist)
        except ValueError:
            raise ValueError(self.gettext('Invalid choice(s): one or more data inputs could not be coerced'))

    def pre_validate(self, form):
        if self.data:
            values = list(c[0] for c in self.choices)
            for d in self.data:
                if d not in values:
                    raise ValueError(self.gettext("'%(value)s' is not a valid choice for this field") % dict(value=d))
  • Вопрос задан
  • 2676 просмотров
Подписаться 3 Оценить 4 комментария
Решения вопроса 1
chewarer
@chewarer Автор вопроса
Решил.
Шаблон с результатами заполнения формы сделал так:
<ul>
    {% for field in form if field.widget.input_type != 'hidden' %}
        {% if field.data %}
            <li>
                {{ field.label }}<br>
                {% if field.type == 'MultiCheckboxField' %}
                    {% for opt in field.data %}
                        {{ dict(field.choices)[opt] }}<br>
                    {% endfor %}
                {% elif field.type == 'RadioField' %}
                    {{ dict(field.choices)[field.data] }}<br>
                {% else %}
                    {{ field.data }}
                {% endif %}
            </li>
        {% endif %}
    {% endfor %}
</ul>


Но мне самому это решение не нравится тем, что приходится в шаблоне колхозить.
Вообще удивительно что в интернете я вообще не нашел чтобы кто-то задавался вопросом как отображать значение, а не ключ выбранного RadioField или CheckboxField.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы