1

This is an old question I never got a satisfactory answer for and I have decided to add a bounty here so that someone might take an interest and figure out what is going on.

The below code works fine locally but when I deploy it to the server I keep getting the below error. I believe the issue is that there is no value at the position images[1] when the code is run. However I don't understand why this only happens on the server and not on my local machine.

  • Local: OS X 10.9.5, Python 2.7.5, Django 1.6.2
  • Server: Ubuntu 12.04, Apache 2.2.22, mod_wsgi Version: 3.3-4ubuntu0.1, Python 2.7.3, Django 1.6

error image

I have marked ### line 143 ### below.

This is related to a previous issue I was having in relation to persisting data from one page to the next in a Django SessionWizardView where it was recommended that I use a session object to store the data I want to persist for use in later pages.

images []
PATH_ONE_IMAGES =   ['P1D1.jpg', 'P2D2.jpg', 'P3D3.jpg']


class SurveyWizardOne(SessionWizardView):                      

    def get_context_data(self, form, **kwargs):
        context = super(SurveyWizardOne, self).get_context_data(form, **kwargs)  
        step = int(self.steps.current)

        if step in range (5, 19):

            if step in (5, 6, 7):
                image = random.choice(PATH_ONE_IMAGES)   
                images.insert(step - 5, image)        

                PATH_ONE_IMAGES.remove(image)
                context['display_image'] = image

                if step == 5:
                    self.request.session['first_image'] = images[0] 
                    self.request.session.get('first_image', 'default_request_session_value') 

                elif step == 6:
                    self.request.session['second_image'] = images[1]  ### line 143 ###
                    self.request.session.get('second_image', 'default_request_session_value') 

                elif step == 7:        
                    self.request.session['third_image'] = images[2] 
                    self.request.session.get('third_image', 'default_request_session_value')

            elif step == 8:                 
                slider_value = self.request.POST.get('slider_value')
                if slider_value is not None:
                    slider_DV_values.insert(step - 5, slider_value)  

                context['first_image'] = self.request.session['first_image']
                context['second_image'] = self.request.session['second_image']
                context['third_image'] = self.request.session['third_image']                 
                context['first_slider'] = slider_DV_values[0]  
                context['second_slider'] = slider_DV_values[1]       
                context['third_slider'] = slider_DV_values[2] 


                ....

                ....

        return context 

If anyone can explain why this error is happening in deployment and not locally and provide a fix it would be greatly appreciated.

Thanks, Deepend

Community
  • 1
  • 1
Deepend
  • 4,057
  • 17
  • 60
  • 101

2 Answers2

3

I'm not good at explaining things, but I'll give it a try.

The key problem is because you have images list defined globally. It works for you locally since you have a single process running under the local django development server. Every request is sharing the same "memory space", accessing the same images variable in the same process.

When you deploy your app to the server, you are entering a multi-process environment - in simple words, the value of images is not shared across multiple processes and, therefore, it is not shared between different requests. In other words, you are inserting into different images lists in different requests:

Do not use global variables, really, please don't.

To fix the issue you need to keep the images somewhere else - inside a session, or in the database:

def get_context_data(self, form, **kwargs):
    context = super(SurveyWizardOne, self).get_context_data(form, **kwargs)  
    step = int(self.steps.current)

    images = self.request.session.get('images', [])

    ...

    self.request.session['images'] = images
    return context
Community
  • 1
  • 1
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
  • That certainly sounds plausible. Unfortunately when I take out the `images []` from the top of the views.py file I keep getting an error "list index out of range" when it gets to the same point (local and on server). Any ideas? – Deepend Jan 04 '15 at 23:40
  • 1
    @Deepend, where are u storing images list now? Please show the code. Thanks. – alecxe Jan 04 '15 at 23:41
  • I just added the line you suggested above `images = self.request.session.get('images', [])` I thought this would add it to the session. Sorry I am only learning Django. Is there a way I should be adding it to the DB or to the Session? – Deepend Jan 04 '15 at 23:44
  • @Deepend ok, sure. Make sure you have the other line that sets the value later in the method. – alecxe Jan 04 '15 at 23:46
0

You could add try-except blocks in order to avoid this error to break your view:

...

if step == 5:
    try:
        self.request.session['first_image'] = images[0] 
        self.request.session.get('first_image', 'default_request_session_value')
    except IndexError:
        # TODO: do something here to debug instead of passing
        # eg.: import pdb; pdb.set_trace(), so you will be able to debug it in the python console where you ran your app
        pass
elif step == 6:
    try:
        self.request.session['second_image'] = images[1]  ### line 143 ###
        self.request.session.get('second_image', 'default_request_session_value')
    except IndexError:
        # TODO: do something here to debug instead of passing
        # eg.: import pdb; pdb.set_trace(), so you will be able to debug it in the python console where you ran your app
        pass
# and so on

...

Hope it gives you a clue to investigate! Good luck!

Lucas Infante
  • 798
  • 6
  • 21