[英]Django SessionWizardView current step missing from form_list after Ajax request
我有一個帶有條件額外步驟的SessionWizardView
進程,在第一步結束時基本上要求'你想添加另一個人',所以我的條件是通過檢查上一步的清理數據生成的;
def function_factory(prev_step):
""" Creates the functions for the condition dict controlling the additional
entrant steps in the process.
:param prev_step: step in the signup process to check
:type prev_step: unicode
:return: additional_entrant()
:rtype:
"""
def additional_entrant(wizard):
"""
Checks the cleaned_data for the previous step to see if another entrant
needs to be added
"""
# try to get the cleaned data of prev_step
cleaned_data = wizard.get_cleaned_data_for_step(prev_step) or {}
# check if the field ``add_another_person`` was checked.
return cleaned_data.get(u'add_another_person', False)
return additional_entrant
def make_condition_stuff(extra_steps, last_step_before_repeat):
cond_funcs = {}
cond_dict = {}
form_lst = [
(u"main_entrant", EntrantForm),
]
for x in range(last_step_before_repeat, extra_steps):
key1 = u"{}_{}".format(ADDITIONAL_STEP_NAME, x)
if x == 1:
prev_step = u"main_entrant"
else:
prev_step = u"{}_{}".format(ADDITIONAL_STEP_NAME, x-1)
cond_funcs[key1] = function_factory(prev_step)
cond_dict[key1] = cond_funcs[key1]
form_lst.append(
(key1, AdditionalEntrantForm)
)
form_lst.append(
(u"terms", TermsForm)
)
return cond_funcs, cond_dict, form_lst
last_step_before_extras = 1
extra_steps = settings.ADDITIONAL_ENTRANTS
cond_funcs, cond_dict, form_list = make_condition_stuff(
extra_steps,
last_step_before_extras
)
我還有一個字典,用於存儲通過會話cookie訪問的密鑰后面的步驟數據,該會話cookie還包含用戶輸入的人員詳細信息列表。 在第一個表單之后,此列表呈現為一個選擇框&on selection觸發對帶有kwargs的SessionWizard
的Ajax調用,該kwargs觸發對返回JsonResponse
的方法的調用;
class SignupWizard(SessionWizardView):
template_name = 'entrant/wizard_form.html'
form_list = form_list
condition_dict = cond_dict
model = Entrant
main_entrant = None
data_dict = dict()
def get_data(self, source_step, step):
session_data_dict = self.get_session_data_dict()
try:
data = session_data_dict[source_step].copy()
data['event'] = self.current_event.id
for key in data.iterkeys():
if step not in key:
newkey = u'{}-{}'.format(step, key)
data[newkey] = data[key]
del data[key]
except (KeyError, RuntimeError):
data = dict()
data['error'] = (
u'There was a problem retrieving the data you requested. '
u'Please resubmit the form if you would like to try again.'
)
response = JsonResponse(data)
return response
def dispatch(self, request, *args, **kwargs):
response = super(SignupWizard, self).dispatch(
request, *args, **kwargs
)
if 'get_data' in kwargs:
data_id = kwargs['get_data']
step = kwargs['step']
response = self.get_data(data_id, step)
# update the response (e.g. adding cookies)
self.storage.update_response(response)
return response
def process_step(self, form):
form_data = self.get_form_step_data(form)
current_step = self.storage.current_step or ''
session_data_dict = self.get_session_data_dict()
if current_step in session_data_dict:
# Always replace the existing data for a step.
session_data_dict.pop(current_step)
if not isinstance(form, TermsForm):
entrant_data = dict()
fields_to_remove = [
'email', 'confirm_email', 'password',
'confirm_password', 'csrfmiddlewaretoken'
]
for k, v in form_data.iteritems():
entrant_data[k] = v
for field in fields_to_remove:
if '{}-{}'.format(current_step, field) in entrant_data:
entrant_data.pop('{}-{}'.format(current_step, field))
if '{}'.format(field) in entrant_data:
entrant_data.pop('{}'.format(field))
for k in entrant_data.iterkeys():
new_key = re.sub('{}-'.format(current_step), u'', k)
entrant_data[new_key] = entrant_data.pop(k)
session_data_dict[current_step] = entrant_data
done = False
for i, data in enumerate(session_data_dict['data_list']):
if data[0] == current_step:
session_data_dict['data_list'][i] = (
current_step, u'{} {}'.format(
entrant_data['first_name'],
entrant_data['last_name']
)
)
done = True
if not done:
session_data_dict['data_list'].append(
(
current_step, u'{} {}'.format(
entrant_data['first_name'],
entrant_data['last_name']
)
)
)
return form_data
如果您在不觸發Ajax調用的情況下單步執行表單,則表單將提交,條件dict將按預期運行。 但是,如果觸發Ajax並將數據返回到表單,則一旦提交表單,會話數據就會消失。 有沒有辦法改變我的設置方式,以便get_data()
可以將數據返回到頁面,而不會破壞會話?
我已經在開發服務器cached_db
SESSION_ENGINE
設置為cached_db
但是我遇到了一個問題,即當您提交第一個條件表單並且系統調用get_next_step()
后跟get_next_step()
get_form_list()
並且條件檢查不再返回第一個條件因為current_step
不再是form_list
一部分,所以我留下了我的默認表單列表並引發了ValueError
。
因此,回顧一下,我逐步瀏覽我的第一個表單,使用'add_another_person'字段觸發第一個條件表單,該字段按預期呈現表單,此時form_list
如下所示;
form_list
u'main_entrant' <class 'online_entry.forms.EntrantForm'>
u'additional_entrant_1' <class 'online_entry.forms.EntrantForm'>
u'terms' <class 'online_entry.forms.TermsForm'>
但是一旦additional_entrant_1
觸發Ajax方法,然后提交, form_list
運行條件dict並且看起來像這樣;
form_list
u'main_entrant' <class 'online_entry.forms.EntrantForm'>
u'terms' <class 'online_entry.forms.TermsForm'>
這可能是會話存儲或會話變為無效的問題嗎?
我總是忽略這個簡單的解釋。
SessionWizardView
的get()
請求重置存儲,我正在制作的Ajax調用作為get請求命中視圖,重置存儲,但也傳回我的信息。
因此,通過簡單覆蓋get()
方法,我已經解決了這個問題;
def get(self, request, *args, **kwargs):
if 'get_data' in kwargs:
data_id = kwargs['get_data']
step = kwargs['step']
response = self.get_data(data_id, step)
else:
self.storage.reset()
# reset the current step to the first step.
self.storage.current_step = self.steps.first
response = self.render(self.get_form())
return response
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.