问题描述:

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

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

网友答案:

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:

  • Global Variable Django
  • python global variable not working in apache

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
网友答案:

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!

相关阅读:
Top