如何在 Flask 中的其他表单提交结束时进行登录?

How to do login at end of other form submission in Flask?

我正在编写一个网络应用程序,您可以在登录(或注册)之前通过表单提出产品请求。这是一种 "try it" 模式,可以降低放弃率。当我们把注册放在首位时——我们有太多人放弃了这项服务,因为他们必须先注册一个账户。通过这种方式,我们可以吸引人们在必须注册之前做出一些努力。

无论如何,我都无法使此模式正常工作。我正在使用烧瓶登录扩展。如果用户未登录,我有一个呈现我的产品请求表单并重定向到登录视图的视图:

@app.route('/customer/gift_request', methods=['GET', 'POST'])
# Note login is NOT required for this.
def gift_request():
    form = GiftRequestForm()
    error = None
    if form.validate_on_submit():
        if current_user.get_id():
            new_gift_request = GiftRequest(
                current_user.id,
                form.giftee_name.data,
                form.giftee_age.data,
                int(form.giftee_sex.data),
                form.event.data,
                form.event_date.data,
                float(form.budget.data))
            try:
                db.session.add(new_gift_request)
                db.session.commit()
                flash("You have successfully submitted a gift request! ",'success')
                return redirect(url_for('customer_home'))
            except:
                error = "Error creating gift request"
        else:
            return redirect(url_for('login', next=request.url)

    return render_template('customer_portal/gift_request.html', form=form, error=error) 

我的登录视图如下:

@app.route('/login', methods=['GET', 'POST'])
def login():
    form = LoginForm()
    error = None
    if form.validate_on_submit():
        user = User.query.filter_by(email=form.email.data).first()
        if user:
            if bcrypt.hashpw(form.password.data.encode('utf-8'), user.password.encode('utf-8')) == user.password:
                login_user(user)
                flash('User {} logged in'.format(current_user.email), 'success')

                # Handle the next URL
                next_url = request.args.get('next')
                if next_url is not url_for('gift_request'):
                    return abort(400)

                return redirect(next_url or url_for('customer_home'))
            else:
                error = "Incorrect password"
        else:
            error = "User not found"
    return render_template("user/landing_page.html",
                       login_form=form,
                       register_form=RegisterForm(),
                       error=error,
                       show_login_modal=True,
                       show_register_modal=False)

请注意,我的登录在我的登录页面上呈现为模式 window。无论如何,我不知道如何在登录后保留我的礼物申请表数据。我该如何传递它?我已经尝试了很多东西——比如把它放在请求中——但感觉很麻烦(而且可能不安全)。此外,在登录提交后——表单数据消失了。它从未传递给登录模板,所以我猜它只是消失了。我在互联网上搜索过,但我似乎无法找到执行此操作的模式。

此外,登录名只是其中的一部分——如果填写礼物请求的人没有登录名,那么我想带他们到注册页面注册一个帐户。但我想如果我弄明白了——我可以采用相同的模式并将其扩展到那个模式。

我认为您可能需要使用会话。它看起来像这样:

if form.validate_on_submit():
    if current_user.get_id():
        session['new_gift_request'] = GiftRequest(
            current_user.id,
            form.giftee_name.data,
            form.giftee_age.data,
            int(form.giftee_sex.data),
            form.event.data,
            form.event_date.data,
            float(form.budget.data))

我已经用过很多次了,从来没有遇到过问题。如果你想让表单数据在没有会话的情况下一直存在,那么你必须跟踪它并将它传递给每个后续模板。

更新

重新阅读您的代码后发现,如果当前用户未登录,则您根本没有保存表单数据。这是一个细微的变化(显然要确保从烧瓶中导入会话):

@app.route('/customer/gift_request', methods=['GET', 'POST'])
# Note login is NOT required for this.
def gift_request():
    form = GiftRequestForm()
    error = None
    if form.validate_on_submit():
        if current_user.get_id():
            new_gift_request = GiftRequest(
                current_user.id,
                form.giftee_name.data,
                form.giftee_age.data,
                int(form.giftee_sex.data),
                form.event.data,
                form.event_date.data,
                float(form.budget.data))
            try:
                db.session.add(new_gift_request)
                db.session.commit()
                flash("You have successfully submitted a gift request! ",'success')
                return redirect(url_for('customer_home'))
            except:
                error = "Error creating gift request"
        else:
            session['giftee_name'] = form.giftee_name.data
            session['giftee_age'] = form.giftee_age.data
            session['giftee_age'] = form.giftee_age.data
            session['giftee_sex'] = int(form.giftee_sex.data)
            session['event'] = form.event.data
            session['event_date'] = form.event_date.data
            session['budget'] = float(form.budget.data)
            return redirect(url_for('login', next=request.url)

    return render_template('customer_portal/gift_request.html', form=form, error=error)