Найти - Пользователи
Полная версия: Flask. Как правильно передать переменную в другую функцию представления
Начало » Web » Flask. Как правильно передать переменную в другую функцию представления
1
Stright
Здравствуйте! Возникла проблема при передаче переменной из одной функции в другую.
В первой функции после получения некоторых данных из формы я вычисляю некоторое значение, которое представляет собой словарь.
Это значение необходимо передать в другую функцию для отображения результата.
@other_tasks.route('/other_tasks/handle_table',
                   methods=['GET', 'POST'])
@login_required
def calculate_characteristic_table():
    form = forms.LeaseCharacteristicForm()
    if form.validate_on_submit():
        details = ... # уточняющие данные для вычислений
        ... # вычисления
        result = {...} # результат, который нужно передать в другую функцию представления
        return redirect(url_for('other_tasks.check_table',
                                result=json.dumps(result)))
    return render_template('other_tasks/details.html', form=form)
@other_tasks.route('/check_table/<result>')
@login_required
def check_table(result):
    result = json.loads(result)
    return render_template('other_tasks/check_table.html', result=result)

Подскажите, пожалуйста, как это правильно сделать, пока ничего более умного, кроме, как присоединить словарь в виде json к url в голову не пришло.
ayb
Так и отдавай результат в первой вьюхе. Вместо редиректа возвращай шаблон и все.
Stright
Но тогда ведь получится, что при обновлении страницы будет происходить повторная отправка формы, как быть в таком случае?
4kpt_IV
Смотрите. Редирект делается в том случае, когда данные формы валидны. Изменяются данные в системе или БД и делается редирект на get. Поясните более подробнее в чем заключается задача, так как Вы что-то не то городите…
Stright
Цель этой части приложения - вывод отчетов (таблиц) из базы данных. Пользователем предварительно загружается архив с каталогом определенной структуры содержащий файлы dbf, нужные данные из которого потом конвертируются в другой формат (использую postgres). Один каталог - это одна база данных по конкретному арендатору (точнее по арендуемому лесному участку) из другой программы. Таких каталогов пользователь может загружать несколько штук, т.е. у каждого каталога (арендатора) в новой бд свой id, который позволяет его идентифицировать данные по нему.
Пока в этой части приложения у меня 3 вьюхи:
1. Здесь пользователю предоставляется возможность выбрать ту часть данных по арендатору (database), по которым он хочет получить отчет. В форме 2 SelectField - выбор арендатора и выбор отчета (значение value отчета совпадает с названием вьюхи, на которую потом будет производиться редирект).
@other_tasks.route('/other_tasks/choose_task', methods=['GET', 'POST'])
@login_required
def choose_task():
    user = current_user._get_current_object()
    form = forms.TaskForm(user=user)
    if form.is_submitted():
        database = Database.query.get_or_404(form.database.data)
        view_func = form.task.data
        return redirect(url_for('other_tasks.{}'.format(view_func),
                                database_id=database.id))
    return render_template('other_tasks/task_choice.html', form=form)
class TaskForm(Form):
    database = SelectField('Укажите целевую базу данных', coerce=int)
    task = SelectField('Выберите задачу', choices=[
        ('calculate_characteristic_table', 'Характеристика лесных насаждений')])
    submit = SubmitField('Отправить')
    def __init__(self, user, *args, **kwargs):
        super(TaskForm, self).__init__(*args, **kwargs)
        self.database.choices = [(database.id, database.name)
                                 for database in user.databases.all()]
2. Во второй я через форму уточняю некоторые данные, необходимые уже для выбранного отчета и затем произвожу расчеты с использованием предварительно написанных классов. На каждый отчет будет своя вьюха. Конкретно для этого отчета в форме всего одно поле BooleanField (которое пока не используется), для других будет больше. Полученный результат я хочу отобразить для просмотра, поэтому после сабмита формы, получения уточняющих данный и вычислений, делаю редирект на третью вьюху, в которую хочу передать словарь с результатом.
other_tasks.route('/other_tasks/handle_table/<int:database_id>',
                   methods=['GET', 'POST'])
@login_required
def calculate_characteristic_table(database_id):
    database = Database.query.get_or_404(database_id)
    user = current_user._get_current_object()
    if database not in user.databases:
        abort(403)
    form = forms.LeaseCharacteristicForm()
    if form.is_submitted():
        details = form.details.data
        table = tables.LeaseCharacteristicTable(database)
        table.get_lease()
        result = table.lease_dict
        # TODO: next line seems wrong, because I join result to URL
        return redirect(url_for('other_tasks.check_table',
                                result=json.dumps(result)))
    return render_template('other_tasks/details.html', form=form)
3. Отображение результата (таблицы с отчетом)
@other_tasks.route('/check_table/<result>')
@login_required
def check_table(result):
    result = json.loads(result)
    return render_template('other_tasks/view_result.html', result=result)
4kpt_IV
Смотрите. Редирект делается в том случае, когда данные формы валидны. Изменяются данные в системе или БД и делается редирект на get.
Поправил form.validate_in_submit() на form.is_submitted(), потому как в этих формах используются только SelectField и BooleanField. Данные не изменяются, а только считываются
4kpt_IV
Вы понимаете как работает http и конкретно redirect?
Stright
Клиенту приходит ответ с url, по которому необходимо отправить get запрос, вроде так
4kpt_IV
Верно. Поэтому есть такие варианты передать данные.

1. Сформировать предварительно get и сделать на него redirect (если много параметров, то этот фокус не пройдет).
2. Записать данные в какое-нибудь временное хранилище передать в get id к нужному полю (для хранения можно использовать redis или sqlite или еще что в голову прийдет).
3. Использовать сессию или печеньки (в этом случае не забыть их подчистить внутри get).
4. Использовать flash (подчищать не придется).
5. Сделать запрос на валидацию формы ajax и, когда с сервера будет ответ просто повторно послать уже get запросом.

Выбирайте любой понравившийся
Stright
Спасибо большое, буду разбираться
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB