Я написал несколько форм с использованием flask-wtf, которые используют FieldList
и FormField
, и я хочу протестировать их с помощью pytest
.Это массовая вставка данных из загруженного файла CSV
Это мои формы:
# myapp/admin/forms.py
from wtforms import Form as NoCsrfForm
class SimpleRegistrationForm(NoCsrfForm):
email = StringField('Email')
username = StringField('Username')
password = StringField('Password')
from flask_wtf import FlaskForm
class BulkUserCreationForm(FlaskForm):
users = FieldList(FormField(SimpleRegistrationForm))
submitted = HiddenField()
submit = SubmitField('Register all')
def is_submitted(self):
from flask import request
return super().is_submitted() and 'submitted' in request.form
Обратите внимание, что я пропускаю импорт и другие вещи.Кроме того, я использовал submitted
, чтобы остановить @app.route
от прохождения validate_on_submit()
.
Это часть моего теста:
# a part of a test
# (...) mumble mumble
from myapp.admin.forms import (
BulkUserCreationForm, SimpleRegistrationForm)
usr_form_1 = SimpleRegistrationForm(username="user1",
email="user1@mail.com",
password="pwd1",)
usr_form_2 = SimpleRegistrationForm(username="user2",
email="user2@mail.com",
password="pwd2",)
usr_form_full = BulkUserCreationForm(
users=[usr_form_1, usr_form_2])
# user issues a POST request
rv = client.post(
url_for('bulk-import-users.edit_users')
follow_redirects=True,
data=usr_form_full.data)
assert something_happened()
Я борюсь за то, как создать аргумент data
для post()
.До сих пор я читал три подхода
- Это решение использует данные в качестве кортежей, но я не понимаю связи между кортежами и формами для чего-то вроде
BulkUserCreationForm.users
Это решение опирается на usr_form_full.data
экземпляра формы, который возвращает словарь.В упомянутом SO ответе, похоже, работает, но в моем случае (и для кода, который я показываю) я получаю сообщение об ошибке вида:
/src/venv/lib/python3.6/site-packages/werkzeug/test.py:349: DeprecationWarning: it's no longer possible to pass dicts as `data`. Use tuples or FileStorage objects instead
Поиск в Googleошибка вернула это (и не намного).В этом решении используются жестко закодированные значения, поэтому вместо этого я выбрал кое-что (я полагаю) более или менее лучше:
data_full = {field.label.field_id: field.data
for form in usr_form_full.users
for field in form}
и передал это атрибуту data
.Это не сработало.По какой-то причине отображаемый атрибут .data
не ведет себя так, как ожидалось, и возвращает другое значение repr
(я ожидал увидеть фактическое значение ).
>>> print(data_full)
{'users-0-email': <wtforms.fields.core.StringField object at 0x7f1704f68cc0>, 'users-0-username': <wtforms.fields.core.StringField object at 0x7f1704fa5e10>, 'users-0-password': <wtforms.fields.core.StringField object at 0x7f1704f539e8>, 'users-1-email': <wtforms.fields.core.StringField object at 0x7f1704f26a90>, 'users-1-username': <wtforms.fields.core.StringField object at 0x7f1704f26f98>, 'users-1-password': <wtforms.fields.core.StringField object at 0x7f1704f26828>}
Короче говоря, нетиз вышеупомянутых подходов работал в моем тесте.Какой правильный подход?Нужно ли передавать значения submit
и submitted
в мой экземпляр формы?