Flask и WTforms: как получить данные из обновленного предварительно заполненного ListField из FormFields - PullRequest
0 голосов
/ 25 января 2020

ОБНОВЛЕНИЕ

После дополнительных копаний относительно моей проблемы, описанной ниже, я считаю, что моя трудность в получении данных из ListField в FormFields связана с тем, что я не могу проверить форма. Когда я использую form.validate_on_submit () вместо form.is_submitted () в маршруте foundItem, я получаю сообщение об ошибке: TypeError: аргумент типа 'CSRFTokenField' не повторяется. Чтение документации мне не помогло. Если я не проверю форму, то вместо данных я получу полный html входной тег из FormField.

-

Я пытаюсь написать небольшое приложение для инвентаризации, чтобы узнать о flask и MongoDB . Пока что я просто пытаюсь реализовать основные функции c (создание, обновление, удаление). В качестве отправной точки моя база данных содержит только позиции с номером детали и количеством. Мне удается добавить новые документы в базу данных, и я могу получить список документов, соответствующих номеру детали. Каждый извлеченный документ используется для предварительного заполнения SearchedItemForm , и эта форма добавляется к listField формы SearchedItemListForm . Это сделано для того, чтобы иметь возможность обновлять количество одного или нескольких элементов одновременно в одном и том же виде. До сих пор я не смог реализовать обновление и был бы признателен за любую помощь. Вот код и лог c.

Формы:

class SearchedItemForm(FlaskForm):
    '''
        Generic form for a single item returned from a search
        in the searchItem page.

    Note:
        This class forms the building block of the class SearchedItemListForm. 
    '''
    id_ = StringField('id', validators=[DataRequired()])
    part_number = StringField('Part number', validators=[DataRequired()])
    quantity = IntegerField('Quantity',validators=[DataRequired()])


class SearchedItemListForm(FlaskForm):
    '''
        Form consisting of a list of SearchItemForm. This is the form
        that is passed to the searchItem page to display the found
        items.
    '''
    items = FieldList(FormField(SearchedItemForm))
    submit = SubmitField('Update')

Поиск осуществляется по маршруту searchItem:

@app.route('/item/search', methods = ['GET', 'POST'])
def searchItem():
    form = SearchForm()
    if form.validate_on_submit():
        query = {form.searchField.data:form.searchValue.data}
        return redirect(url_for('foundItem', query=query))

    return render_template('searchItem.html', title='Search item',
                           form=form)

Из поиска Я получаю поле поиска, значение поиска и создается запрос, который передается в маршрут foundItem.

@app.route('/item/result', methods = ['GET', 'POST'])
def foundItem():
    query = json.loads(request.args.get('query').replace("'", "\""))
    form, pnList = listOfSearchedItems(query)

    if form.is_submitted():
        for item in form.items:
            print(item.quantity.data)
            # some code to update db

    return render_template('foundItem.html', title='Search result',
                           form=form, pnList=pnList)

Запрос передается функции listOfSearchedItems и форме тип SearchedItemListForm предварительно заполнен и возвращается вместе со списком номеров деталей. Эти параметры передаются в шаблон foundItem , где они отображаются, и количество любого элемента может быть изменено. Моя сложность заключается в представлении формы. Прежде всего, если я использую if form.validate_on_submit (), я получаю сообщение об ошибке TypeError: аргумент типа 'CSRFTokenField' не повторяется. Ясно, что есть кое-что, чего я не понимаю с защитой CSRF. Что еще более важно, я не могу получить значения количества, так как print (item.quantity.data) печатает полный входной тег html вместо самого количества, и здесь я был бы признателен за некоторую помощь.

Для завершения:

def listOfSearchedItems(query):
    '''
        return list of queried items from initial search
        in the searchItem view.

    Args:
        query(dict): dictionnary for the query

    Returns:
        items(SearchedItemForm): form containing returned items
        pnList: list of part numbers of returned items
    '''
    items = SearchedItemListForm()
    pnList = []

    results = mongo.db.optics.find(query)

    for result in results:
        item = SearchedItemForm()
        item.id_.data = str(result['_id'])
        item.part_number.data = result['part_number']
        item.quantity.data = result['quantity']
        pnList.append(result['part_number'])
        items.items.append_entry(item)

    return items, pnList

и шаблон foundItem

{% extends 'base.html' %}

{% block content %}
<h1>{{ title }}</h1>
{% if form.items %}
    {% set pnList_id=0 %}
    <form action="" method="post">
      {{ form.hidden_tag() }}
      <table>
          <tr>
            <th>Part number</th>
            <th>Quantity</th>
          </tr>
          {% for item in form.items %}
          <tr>
            <td><a href="#">{{ pnList[pnList_id] }}</a></td>
            <td>{{ item.quantity.data }}</td>
          </tr>
          {% set pnList_id=pnList_id+1 %}
          {% endfor %}
      </table>
      {{ form.submit() }}
    </form>
    {% endif %}
{% endblock %}

1 Ответ

0 голосов
/ 29 января 2020

Я наконец нашел ответ здесь: fill-wtforms-formfield-fieldlist-with-data-results-results- in- html -in-fields .

Функция append_entry a ListField ожидает данные, а не форму, что было моей ошибкой. Передача словаря с правильными ключами / значениями работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...