Как создать динамические поля в WTForms
Я пытаюсь создать форму в WTForms с динамическими полями в соответствии с этой документацией http://wtforms.simplecodes.com/docs/1.0.2/specific_problems.html#dynamic-form-composition
У меня есть этот класс подформ, который позволяет пользователям выбирать предметы для покупки из списка:
class Item(Form):
itmid = SelectField('Item ID')
qty = IntegerField('Quantity')
class F(Form):
pass
Будет больше чем одна категория товаров для покупок, поэтому я бы хотел создать динамическое поле выбора, основанное на том, какие категории выберет пользователь:
fld = FieldList(FormField(Item))
fld.append_entry()
но я получаю следующую ошибку:
AttributeError: 'UnboundField' object has no attribute 'append_entry'
Я делаю что-то не так, или нет способа сделать это в WTForms?
Ответы
Ответ 1
Сегодня я столкнулся с этим вопросом и закончил с этим. Надеюсь, это поможет будущим людям.
RecipeForm.py
class RecipeForm(Form):
category = SelectField('Category', choices=[], coerce=int)
...
views.py
@mod.route('/recipes/create', methods=['POST'])
def validateRecipe():
categories = [(c.id, c.name) for c in g.user.categories.order_by(Category.name).all()]
form = RecipeForm(request.form)
form.category.choices = categories
...
@mod.route('/recipes/create', methods=['GET'])
def createRecipe():
categories = [(c.id, c.name) for c in g.user.categories.order_by(Category.name).all()]
form = RecipeForm(request.form)
form.category.choices = categories
return render_template('recipes/createRecipe.html', form=form)
Я нашел этот пост полезным
Ответ 2
class BaseForm(Form):
@classmethod
def append_field(cls, name, field):
setattr(cls, name, field)
return cls
from forms import TestForm
form = TestForm.append_field("do_you_want_fries_with_that",BooleanField('fries'))(obj=db_populate_object)
Я использую расширенный класс BaseForm для всех моих форм и имею удобную функцию append_field в классе.
Возвращает класс с добавленным полем, поскольку экземпляры (полей формы) не могут добавлять поля.
Ответ 3
Проводка без написания полного кода или тестирования кода, но, возможно, это даст вам некоторые идеи. Также это может помочь только при заполнении необходимых данных.
Вам нужно заполнить choices
для SelectField
, чтобы видеть данные и быть в состоянии выбрать их. Где вы это заполняете? Начальная заливка должна быть в определении формы, но если вам нравится динамический, я бы предложил изменить ее в том месте, где вы создаете эту форму для показа пользователю. Подобно представлению, в котором вы выполняете несколько form = YourForm()
, а затем передаете его в шаблон.
Как заполнить поле выбора формы с помощью вариантов? У вас должен быть список кортежей, а затем что-то вроде этого:
form.category_select.choices = [(key, categories[key]) for key in categories]
form.category_select.choices.insert(0, ("", "Some default value..."))
categories
здесь должен быть словарь, содержащий ваши категории в формате {1:'One', 2:'Two',...}
Итак, если вы назначите что-то для выбора при определении формы, у него будут такие данные с самого начала и где вам нужно иметь пользовательские категории, просто перепишите их в представление.
Надеюсь, что это даст вам некоторые идеи, и вы можете двигаться вперед:)
Ответ 4
Пробовал ли вы вызов append_entry()
в экземпляре формы вместо определения FieldList?
class F(Form)
fld = FieldList(SelectField(Item))
form = F()
form.fld.append_entry()
Ответ 5
Документация WTForms: класс wtforms.fields.SelectField
Выберите поля с динамическими значениями выбора:
class UserDetails(Form):
group_id = SelectField(u'Group', coerce=int)
def edit_user(request, id):
user = User.query.get(id)
form = UserDetails(request.POST, obj=user)
form.group_id.choices = [(g.id, g.name) for g in Group.query.order_by('name')]