2016-03-02 2 views
0

У меня возникла проблема с установкой значений по умолчанию для FieldForm в WTForms.WTForm FormField заполняет значения

models.py

class RepairCategory(db.Model): 
    name = ... 
class Repair(db.Model): 
    price = .. 
    category_id [FK] = ... 
    product_id [FK] 
class Product(db.Model): 
    name = ... 
    description = ... 
    color = ... 

ProductBase содержит только атрибуты, которые соответствуют дб Модель продукта.
forms.py

class NewRepair(Form): 
    #this is okay - it get's populated 
    repair_category = QuerySelectField("Repair category", 
             query_factory=get_categories)      
    price = DecimalField() 

class ProductBase(Form): 
    name = StringField("Name ", validators=[DataRequired(), Length(1, 64)]) 
    color = StringField("Color ", validators=[DataRequired(), Length(1, 64)]) 
    description = TextAreaField("Description") 
    active = BooleanField() 

class Product(Form): 
    base_product = FormField(ProductBase) 
    add_repairs = FormField(NewRepair) 
    submit = SubmitField('Submit') 

The add_repairs содержит форму, которую я хочу использовать в целях создания ремонта. Base_product - это форма, в которой, в идеале, я хочу передать obj = product в представлениях, поэтому значения по умолчанию заселяются автоматически. Я также хочу использовать form.populate_obj(), как раз в форме base_product.

вот как я создаю форму продукта в виде:

def make_product_form(form=None, product=None, **kwargs): 
    form = form() 
    form.base_product.obj = product   
    return form 

А потом, при обращении с постами, я хочу сделать:

def product(id): 
    product = Product.query.get_or_404(id) 

    form = make_product_form(form=Product,product=product) 

    if form.validate_on_submit(): 
     product_form = form.base_product 
     product_form.populate_obj(product) 

Однако base_form от вида продукта, не заполняется значениями по умолчанию из существующего объекта.

Любые предложения о том, как достичь этого? Спасибо :)

+1

Разве ваша функция 'make_product_form' не выдает исключение 'AttributeError'? В вашем классе 'ProductBase' нет атрибута' obj', поэтому строка 'form.base_product.obj = product' не должна работать. Вы также не отправляли код для класса EditProduct. – kchomski

ответ

0

После обнаружения, что вы можете запустить код непосредственно из трассировки стека Колбу в браузере (? Как это круто), я нашел решение моей проблемы.

Ключ в том, что при создании главной формы продукта (в make_product_form()), когда я
form.base_product.obj я не доступ к атрибуту OBJ.

Однако form.base_product.form.process(obj=product) сделал трюк! Ключ используется base_product. Форма, чтобы получить доступ к форме в пределах FormField. Вот все атрибуты form.base_product. Реж() вычисляется только после того, как вида = формы() в make_product_form():

dir(form.base_product) 
[#ommitted some attributes#, 
'__weakref__', '_formfield', '_obj', '_run_validation_chain', 
'_translations', 'data', 'default', 'description', 
'do_not_call_in_templates', 'errors', 'filters', 'flags', 'form', 
'form_class', 'gettext', 'id', 'label', 'meta', 'name', 'ngettext', 
'object_data', 'populate_obj', 'post_validate', 'pre_validate', 
'process', 'process_data', 'process_errors', 'process_formdata', 
'raw_data', 'render_kw', 'separator', 'short_name', 'type', 
'validate', 'validators', 'widget' ] 

Что это свидетельствует о том, что на самом деле форме.base_product - это поле, а не форма, а form.base_product.form получил форму ProductBase.

Надежда это полезно

** Обновление **
я должен был использовать процесс (OBJ = продукта) только на запросах GET, чтобы предварительно заполнить форму, в противном случае на POST, фактической формы данных отбрасывается.

0

Использовать форму process метод заполнения полей формы значениями атрибутов объекта.
Использовать форму populate_obj метод заполнения атрибутов объекта значениями из полей формы.
Примечание: Имена атрибутов объекта должны соответствовать именам с полями формы.

process пример:

>>> class MyObj(object): 
...  name = "object's name" 
>>> from wtforms import Form, StringField 
>>> class MyForm(Form): 
...  name = StringField("Form's name") 
>>> my_obj = MyObj() 
>>> my_obj.name 
"object's name" 
>>> my_form = MyForm() 
>>> print my_form.name.data 
None 
>>> my_form.process(obj=my_obj) 
>>> my_form.name.data 
"object's name" 

populate_obj пример:

>>> my_form.name.data = "Form's name" 
>>> my_form.name.data 
"Form's name" 
>>> my_obj.name 
"object's name" 
>>> my_form.populate_obj(my_obj) 
>>> my_obj.name 
"Form's name" 
+0

Большое спасибо за ответ! :) Ваше предложение будет работать, если бы я имел доступ к форме (так form.base_form). Мне удалось решить проблему самостоятельно –

Смежные вопросы