如果我有3个步骤的注册,那将使用3个表格。
这样的东西,只是为了证明:
@app.route('/form/step1', methods=['GET', 'POST'])
def form_step1():
form = form_step_1(request.form)
...validate()...
return render_template('register.html', form=form)
@app.route('/form/step2', methods=['GET', 'POST'])
def form_step2():
form = form_step_2(request.form)
...validate()...
return render_template('register.html', form=form)
@app.route('/form/step3', methods=['GET', 'POST'])
def form_step3():
form = form_step_3(request.form)
...validate()...
return render_template('register.html', form=form)
在这三个步骤之间处理数据的正确方法是什么?所有数据都应该在步骤3结束时提交到数据库。但是表单之间的后退操作应该再次填充前一个表单。
为此目的使用会话似乎很糟糕。
答案 0 :(得分:3)
我个人建议使用会话对象将数据从一个表单传递到另一个表单。如果您有少量数据,那么您只需使用烧瓶具有的cookie实现即可。否则,you can override the default sessions object to store sessions data server side using Redis. This lets you use session objects without paying the price of storing lots of data in cookies.这意味着您可以执行类似
的操作@app.route('/form/step1', methods=['GET', 'POST'])
def form_step1():
form1 = form_step_1(request.POST)
user_id = current_user.user_id # If you're using flask-login
...validate()...
# dictionary that holds form1, form2, etch
form_data = {"form1": form1, "form2": None, "Form3"=None}
flask.session[user_id] = form_data
redirct_to(url_for("form_step2"))
return render_template('register.html', {'form':form1})
@app.route('/form/step2', methods=['GET', 'POST'])
def form_step2():
form1 = session[user_id][form1]
# A simpler way than passing the whole form is just the data
# you want but for this answer I'm just specifying the whole form.
form = form_step_2(form1)
user_id = current_user.user_id # If you're using flask-login
...validate()...
# dictionary that holds form1, form2, etch
flask.session[user_id]["form2"] = form2
redirct_to(url_for("form_step3"))
return render_template('register.html', form=form)
答案 1 :(得分:0)
如果您没有任何理由担心POST劫持表单数据,可以使用第2和第3个视图中的隐藏表单字段来传递数据。想一想......
forms.py
# override EACH form's init to change the widget for each field to a hidden widget if is_hidden kwarg passed.
class form_step_1(forms.Form):
def __init__(self, *args, **kwargs):
is_hidden = kwargs.pop('is_hidden', None)
super(FormName, self).__init__(*args, **kwargs)
if is_hidden:
for field in self.fields:
self.fields[field].widget = forms.HiddenInput()
# Be sure to do this for each form with hidden input needed
views.py
@app.route('/form/step1', methods=['GET', 'POST'])
def form_step1():
form1 = form_step_1(request.POST)
...validate()...
return render_template('register.html', {'form':form1})
@app.route('/form/step2', methods=['GET', 'POST'])
def form_step2():
form1 = form_step_1(request.POST, is_hidden=True)
hidden_forms =[form1]
form2 = form_step_2(request.POST)
...validate()...
return render_template('register.html', {'form':form2, 'hidden_forms':hidden_forms})
@app.route('/form/step3', methods=['GET', 'POST'])
def form_step3():
form1 = form_step_1(request.POST, is_hidden=True)
form2 = form_step_2(request.POST, is_hidden=True)
hidden_forms =[form1, form2]
form = form_step_3(request.form)
...validate()...
if form.is_valid():
# do stuff, save to DB
form1.save()
form2.save()
form3.save()
return HttpReturnRedirect('/success_page/') # Always Redirect after posting form
# if not valid, show again.
return render_template('register.html', {'form':form, 'hidden_forms':hidden_forms })
template.html (assuming you are using a single template for each page
<form action="." etc>
{% csrf_token %}
{{ form }}
{% for each_form in hidden_forms %}
{{ each_form }}
<!-- your submit button -->
</form>
现在,当您的表单在步骤3中转到POST时,如果有效,则可以使用前面步骤中的每个表单数据。
如果您想要一个愚蠢的解决方案(需要更多工作),请查看Django FormWizard