简体   繁体   中英

How to re-initialize a session variable in a Django SessionWizardView

I am using a Djago SessionWizardView to divide a survey application over multiple pages. The code below is designed to select one image at random from the PATH_ONE_IMAGES list on each step, display it to the user, and then remove it from the list, so that it cannot be selected a second time, until all the images are gone.

This works fine, but when I revisit the survey in the same browser the PATH_ONE_IMAGES is still empty despite my re-initializing it at the start. It works fine if I delete the browser history or if use a different browser each time I use it but I keep getting the below error when I revisit the application using the same browser.

IndexError at /surveyone/

list index out of range

I am only learning how to use Session variables but I thought that by re-initializing PATH_ONE_IMAGES as containing all 9 of the jpgs as I do below at the top of my SessionWizardView that the list would be "re-populated" each time.

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']) 

Is this not correct?

From my debug script below I can see that the first time I visit the application with a 'fresh' browser the PATH_ONE_IMAGES has 9 items stored in it.

logger.debug('\n\nThis is the available list of PATH_ONE_IMAGES in 5: %s', PATH_ONE_IMAGES)

I then select one of these PATH_ONE_IMAGES at random, display it to the user and then remove it from the list.

first_image = random.choice(PATH_ONE_IMAGES)   
PATH_ONE_IMAGES.remove(first_image)               
context['display_image'] = first_image

My issue is that when I revisit a second time using the same browser the list is empty, even though I re-initialize it at the top.

Question: How do I repopulate my PATH_ONE_IMAGES list each time the user revisits the application even when using the same browser?

I apologize if I am using the wrong terminology, I hope you can understand what I mean.

Note: I need to store PATH_ONE_IMAGES as a session variable due to an issue I had previously with using Global variables and Multi-threaded processing .

My Code

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')    
                ....
                ....

Any help, is as always, much appreciated

You should initialize your variable path_one_images only on the first wizard step:

....

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               

....

and maybe you need to adopt the same approach for images and slider_DV_values variables.

Actually when you visit with the same browser you are not initialising, you are actually using the same PATH_ONE_IMAGES , that you saved at the 9th step. This is happening because if this line of code -

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.

I will describe the scenario, what is happening in your case -

  1. When the first time you open the browser there is nothing in the session . So the first time the above code will assign ['P1D1.jpg', 'P2D2.jpg', 'P3D3.jpg', 'P4D4.jpg', 'P5D5.jpg', 'P6D6.jpg', 'P7D7.jpg', 'P8D8.jpg', 'P9D9.jpg'] inside PATH_ONE_IMAGES .

  2. continues until PATH_ONE_IMAGES is empty .... no error..

  3. Now you refreshed the browser, but remember session does not get cleared for only refreshing the browser, therefore the PATH_ONE_IMAGE , that you saved in the session is not cleared and thus contains an empty list of item that was saved at last step.

So, somehow you have to clear the variable when it is the first step. You can take the code sample that @salvatore provided and add a check to initialise it only at step 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', [])`

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM