如何在 Django SessionWizardView 中重新初始化会话变量
How to re-initialize a session variable in a Django SessionWizardView
我正在使用 Djago SessionWizardView 将调查应用程序分成多个页面。下面的代码旨在每一步从PATH_ONE_IMAGES
列表中随机select一张图片,展示给用户,然后从列表中移除,这样就不能select 第二次,直到所有图像都消失了。
这很好用,但是当我在同一个浏览器中重新访问调查时,PATH_ONE_IMAGES
仍然是空的,尽管我在开始时重新初始化了它。如果我删除浏览器历史记录或者每次使用不同的浏览器,它都可以正常工作,但是当我使用相同的浏览器重新访问应用程序时,我会不断收到以下错误。
IndexError at /surveyone/
list index out of range
我只是在学习如何使用会话变量,但我认为通过将 PATH_ONE_IMAGES
重新初始化为包含所有 9 个 jpg,就像我在 SessionWizardView
顶部所做的那样,列表每次都是 "re-populated"。
PATH_ONE_IMAGES = self.request.session.get('path_one_images', ['P1D1.jpg', 'P2D2.jpg', 'P3D3.jpg', 'P4D4.jpg', 'P5D5.jpg', 'P6D6.jpg', 'P7D7.jpg', 'P8D8.jpg', 'P9D9.jpg'])
这不正确吗?
从下面的调试脚本中我可以看到,当我第一次使用 'fresh' 浏览器访问该应用程序时,PATH_ONE_IMAGES
中存储了 9 个项目。
logger.debug('\n\nThis is the available list of PATH_ONE_IMAGES in 5: %s', PATH_ONE_IMAGES)
然后我 select 随机 PATH_ONE_IMAGES
其中之一,将其显示给用户,然后将其从列表中删除。
first_image = random.choice(PATH_ONE_IMAGES)
PATH_ONE_IMAGES.remove(first_image)
context['display_image'] = first_image
我的问题是,当我使用同一个浏览器再次访问时,列表是空的,即使我在顶部重新初始化了它。
问题:如何在用户每次重新访问应用程序时重新填充我的 PATH_ONE_IMAGES
列表,即使使用相同的浏览器?
如果我使用了错误的术语,我深表歉意,希望您能理解我的意思。
注意:由于 an issue I had previously with using Global variables and Multi-threaded processing,我需要将 PATH_ONE_IMAGES
存储为会话变量。
我的代码
class SurveyWizardOne(SessionWizardView):
def get_context_data(self, form, **kwargs):
context = super(SurveyWizardOne, self).get_context_data(form, **kwargs)
step = int(self.steps.current)
PATH_ONE_IMAGES = self.request.session.get('path_one_images', ['P1D1.jpg', 'P2D2.jpg', 'P3D3.jpg', 'P4D4.jpg', 'P5D5.jpg', 'P6D6.jpg', 'P7D7.jpg', 'P8D8.jpg', 'P9D9.jpg'])
images = self.request.session.get('images', [])
slider_DV_values = self.request.session.get('slider_DV_values', [])
if step in range (5, 19):
self.request.session['path_one_images'] = PATH_ONE_IMAGES
self.request.session['images'] = images
self.request.session['slider_DV_values'] = slider_DV_values
if step == 5:
logger.debug('\n\nThis is the available list of PATH_ONE_IMAGES in 5: %s', PATH_ONE_IMAGES)
first_image = random.choice(PATH_ONE_IMAGES)
PATH_ONE_IMAGES.remove(first_image)
context['display_image'] = first_image
images.insert(0, first_image)
self.request.session['first_image'] = images[0]
self.request.session.get('first_image')
elif step == 6:
logger.debug('\n\nThis is the available list of PATH_ONE_Images in 6: %s', PATH_ONE_IMAGES)
second_image = random.choice(PATH_ONE_IMAGES)
PATH_ONE_IMAGES.remove(second_image)
context['display_image'] = second_image
images.insert(1, second_image)
self.request.session['second_image'] = images[1]
self.request.session.get('second_image')
....
....
任何帮助,一如既往,非常感谢
您应该只在向导的第一步初始化您的变量path_one_images
:
....
step = int(self.steps.current)
if step == 0:
self.request.session['path_one_images'] = ['P1D1.jpg', 'P2D2.jpg', 'P3D3.jpg', 'P4D4.jpg', 'P5D5.jpg', 'P6D6.jpg', 'P7D7.jpg', 'P8D8.jpg', 'P9D9.jpg']
PATH_ONE_IMAGES = self.request.session.get('path_one_images', [])
images = self.request.session.get('images', [])
slider_DV_values = self.request.session.get('slider_DV_values', [])
if step in range (5, 19):
# You don't need to reinit here your session variable
# self.request.session['path_one_images'] = PATH_ONE_IMAGES
....
也许您需要对 images
和 slider_DV_values
变量采用相同的方法。
实际上,当您使用同一个浏览器访问时,您并没有初始化,您实际上使用的是您在 9th
步骤中保存的同一个 PATH_ONE_IMAGES
。发生这种情况是因为如果这行代码 -
PATH_ONE_IMAGES = self.request.session.get('path_one_images', ['P1D1.jpg', 'P2D2.jpg', 'P3D3.jpg', 'P4D4.jpg', 'P5D5.jpg', 'P6D6.jpg', 'P7D7.jpg', 'P8D8.jpg', 'P9D9.jpg'])
Note that, get
only return the second parameter if the provided key (first parameter) is not present in a dictionary, neither it checks what the value is nor does it initialises the dictionary with the provided default value (second parameter). So with this line code, the value of path_on_images
inside the session is never updated, it will only check if that value exists or not - it won't check for empty value, None or anything else.
我将描述场景,您的情况 -
第一次打开浏览器时session
里面什么都没有。所以上面的代码第一次会在PATH_ONE_IMAGES
.
里面赋值['P1D1.jpg', 'P2D2.jpg', 'P3D3.jpg', 'P4D4.jpg', 'P5D5.jpg', 'P6D6.jpg', 'P7D7.jpg', 'P8D8.jpg', 'P9D9.jpg']
继续直到 PATH_ONE_IMAGES
为空....没有错误..
现在您刷新了浏览器,但请记住 session
不会因为仅刷新浏览器而被清除,因此您保存在会话中的 PATH_ONE_IMAGE
不会被清除因此包含在最后一步保存的项目的空列表。
因此,您必须以某种方式在第一步时清除变量。您可以采用@salvatore 提供的代码示例,并添加一个检查以仅在第 0 步对其进行初始化。
step = int(self.steps.current)
if step == 0:
self.request.session['path_one_images'] = ['P1D1.jpg', 'P2D2.jpg', 'P3D3.jpg', 'P4D4.jpg', 'P5D5.jpg', 'P6D6.jpg', 'P7D7.jpg', 'P8D8.jpg', 'P9D9.jpg']
PATH_ONE_IMAGES = self.request.session.get('path_one_images', [])
images = self.request.session.get('images', [])
slider_DV_values = self.request.session.get('slider_DV_values', [])`
我正在使用 Djago SessionWizardView 将调查应用程序分成多个页面。下面的代码旨在每一步从PATH_ONE_IMAGES
列表中随机select一张图片,展示给用户,然后从列表中移除,这样就不能select 第二次,直到所有图像都消失了。
这很好用,但是当我在同一个浏览器中重新访问调查时,PATH_ONE_IMAGES
仍然是空的,尽管我在开始时重新初始化了它。如果我删除浏览器历史记录或者每次使用不同的浏览器,它都可以正常工作,但是当我使用相同的浏览器重新访问应用程序时,我会不断收到以下错误。
IndexError at /surveyone/
list index out of range
我只是在学习如何使用会话变量,但我认为通过将 PATH_ONE_IMAGES
重新初始化为包含所有 9 个 jpg,就像我在 SessionWizardView
顶部所做的那样,列表每次都是 "re-populated"。
PATH_ONE_IMAGES = self.request.session.get('path_one_images', ['P1D1.jpg', 'P2D2.jpg', 'P3D3.jpg', 'P4D4.jpg', 'P5D5.jpg', 'P6D6.jpg', 'P7D7.jpg', 'P8D8.jpg', 'P9D9.jpg'])
这不正确吗?
从下面的调试脚本中我可以看到,当我第一次使用 'fresh' 浏览器访问该应用程序时,PATH_ONE_IMAGES
中存储了 9 个项目。
logger.debug('\n\nThis is the available list of PATH_ONE_IMAGES in 5: %s', PATH_ONE_IMAGES)
然后我 select 随机 PATH_ONE_IMAGES
其中之一,将其显示给用户,然后将其从列表中删除。
first_image = random.choice(PATH_ONE_IMAGES)
PATH_ONE_IMAGES.remove(first_image)
context['display_image'] = first_image
我的问题是,当我使用同一个浏览器再次访问时,列表是空的,即使我在顶部重新初始化了它。
问题:如何在用户每次重新访问应用程序时重新填充我的 PATH_ONE_IMAGES
列表,即使使用相同的浏览器?
如果我使用了错误的术语,我深表歉意,希望您能理解我的意思。
注意:由于 an issue I had previously with using Global variables and Multi-threaded processing,我需要将 PATH_ONE_IMAGES
存储为会话变量。
我的代码
class SurveyWizardOne(SessionWizardView):
def get_context_data(self, form, **kwargs):
context = super(SurveyWizardOne, self).get_context_data(form, **kwargs)
step = int(self.steps.current)
PATH_ONE_IMAGES = self.request.session.get('path_one_images', ['P1D1.jpg', 'P2D2.jpg', 'P3D3.jpg', 'P4D4.jpg', 'P5D5.jpg', 'P6D6.jpg', 'P7D7.jpg', 'P8D8.jpg', 'P9D9.jpg'])
images = self.request.session.get('images', [])
slider_DV_values = self.request.session.get('slider_DV_values', [])
if step in range (5, 19):
self.request.session['path_one_images'] = PATH_ONE_IMAGES
self.request.session['images'] = images
self.request.session['slider_DV_values'] = slider_DV_values
if step == 5:
logger.debug('\n\nThis is the available list of PATH_ONE_IMAGES in 5: %s', PATH_ONE_IMAGES)
first_image = random.choice(PATH_ONE_IMAGES)
PATH_ONE_IMAGES.remove(first_image)
context['display_image'] = first_image
images.insert(0, first_image)
self.request.session['first_image'] = images[0]
self.request.session.get('first_image')
elif step == 6:
logger.debug('\n\nThis is the available list of PATH_ONE_Images in 6: %s', PATH_ONE_IMAGES)
second_image = random.choice(PATH_ONE_IMAGES)
PATH_ONE_IMAGES.remove(second_image)
context['display_image'] = second_image
images.insert(1, second_image)
self.request.session['second_image'] = images[1]
self.request.session.get('second_image')
....
....
任何帮助,一如既往,非常感谢
您应该只在向导的第一步初始化您的变量path_one_images
:
....
step = int(self.steps.current)
if step == 0:
self.request.session['path_one_images'] = ['P1D1.jpg', 'P2D2.jpg', 'P3D3.jpg', 'P4D4.jpg', 'P5D5.jpg', 'P6D6.jpg', 'P7D7.jpg', 'P8D8.jpg', 'P9D9.jpg']
PATH_ONE_IMAGES = self.request.session.get('path_one_images', [])
images = self.request.session.get('images', [])
slider_DV_values = self.request.session.get('slider_DV_values', [])
if step in range (5, 19):
# You don't need to reinit here your session variable
# self.request.session['path_one_images'] = PATH_ONE_IMAGES
....
也许您需要对 images
和 slider_DV_values
变量采用相同的方法。
实际上,当您使用同一个浏览器访问时,您并没有初始化,您实际上使用的是您在 9th
步骤中保存的同一个 PATH_ONE_IMAGES
。发生这种情况是因为如果这行代码 -
PATH_ONE_IMAGES = self.request.session.get('path_one_images', ['P1D1.jpg', 'P2D2.jpg', 'P3D3.jpg', 'P4D4.jpg', 'P5D5.jpg', 'P6D6.jpg', 'P7D7.jpg', 'P8D8.jpg', 'P9D9.jpg'])
Note that,
get
only return the second parameter if the provided key (first parameter) is not present in a dictionary, neither it checks what the value is nor does it initialises the dictionary with the provided default value (second parameter). So with this line code, the value ofpath_on_images
inside the session is never updated, it will only check if that value exists or not - it won't check for empty value, None or anything else.
我将描述场景,您的情况 -
第一次打开浏览器时
session
里面什么都没有。所以上面的代码第一次会在PATH_ONE_IMAGES
. 里面赋值继续直到
PATH_ONE_IMAGES
为空....没有错误..现在您刷新了浏览器,但请记住
session
不会因为仅刷新浏览器而被清除,因此您保存在会话中的PATH_ONE_IMAGE
不会被清除因此包含在最后一步保存的项目的空列表。
['P1D1.jpg', 'P2D2.jpg', 'P3D3.jpg', 'P4D4.jpg', 'P5D5.jpg', 'P6D6.jpg', 'P7D7.jpg', 'P8D8.jpg', 'P9D9.jpg']
因此,您必须以某种方式在第一步时清除变量。您可以采用@salvatore 提供的代码示例,并添加一个检查以仅在第 0 步对其进行初始化。
step = int(self.steps.current)
if step == 0:
self.request.session['path_one_images'] = ['P1D1.jpg', 'P2D2.jpg', 'P3D3.jpg', 'P4D4.jpg', 'P5D5.jpg', 'P6D6.jpg', 'P7D7.jpg', 'P8D8.jpg', 'P9D9.jpg']
PATH_ONE_IMAGES = self.request.session.get('path_one_images', [])
images = self.request.session.get('images', [])
slider_DV_values = self.request.session.get('slider_DV_values', [])`